Breezefinder: Citizen Wind Energy

Anyone who has walked down Tenth Avenue after a rainstorm is familiar with the broken umbrellas scattered everywhere–stuffed into trashcans, abandoned in corners. If the city is so windy, why aren’t there wind turbines everywhere?

As it turns out, the technology to harness unpredictable urban winds is pretty new, but an even bigger problem is a lack of data. Breezefinder is a citizen science solution to the question: where is wind energy?

Main challenges: coding with string and char functions, mastering GPS and phone functions in a relatively new Arduino library, power supply

Eventful mishaps: setting the FONA on fire (just a little)

Next time: a more appropriately designed housing, consolidated power management, no fire

I am really proud of how this project turned out and would like to take it further in the future. Right now my sample data is available @breezefinder on Twitter, and if I had the chance, I’d love to have several Breezefinder feeds collecting data. The Instructable for making Breezefinder yourself is here.

The code:

#include “Adafruit_FONA.h”
#include <SoftwareSerial.h>

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

const int analogInPin = A0;  // Analog input pin that the anemometer is attached to
float outputValue = 0; //value output to PWM (analog out) controls m/s reading

int sensorValue = 0;        // value read from the pot
int threshold = 10.00;          // change this to your desired triggering anemometer reading
char sendto[21] = “40404”;
String label = String(“Yes! windspeed = “);
String label2 = String(” GPS location is “);
String messageString = String();
char message[141];

void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);

Serial.println(F(“Breezefinder SMS test”));
Serial.println(F(“Initializing….(May take 3 seconds)”));

// make it slow so its easy to read!
fonaSerial->begin(9600);
if (! fona.begin(*fonaSerial)) {
Serial.println(F(“Couldn’t find FONA”));
while(1);
}
Serial.println(F(“FONA is OK”));

// Print SIM card IMEI number.
char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
uint8_t imeiLen = fona.getIMEI(imei);
if (imeiLen > 0) {
Serial.print(“SIM card IMEI: “); Serial.println(imei);
}

Serial.println(F(“FONA is OK”));
// Try to enable GPRS

Serial.println(F(“Enabling GPS…”));
fona.enableGPS(true);

Serial.println(“FONA Ready”);
}

void loop() {
// read the analog in value:
sensorValue = analogRead(analogInPin);

// map the incoming sensor data to the range of the digital out:

/* analog inputs will always bring in a value from 0-1023,
and the second set of numbers in the map function
describe the resulting range.

The sensor is supposed to have a linear relationship from voltage to wind speed,
so this math should result in a multiplier you can use to figure out m/s from the anlog input.
1023/32.4=31.57
*/
outputValue = map(sensorValue, 80, 500, 0, 31.57); //because 1023 is the normal value, but it maps to 5V in the Arduino, I changed it to 500.
//80 is the minimum value of the serial log
// print the results to the serial monitor:
Serial.print(“sensor = ” );
Serial.print(sensorValue);
Serial.print(“\t output = “);
Serial.println(outputValue);

// alter LED state
if (outputValue > 9){ //now you can evaluate for actual wind speed
Serial.print(“YES”);
digitalWrite (ledPin, HIGH);}
else {
Serial.print (“NO”);
digitalWrite (ledPin, LOW);
}
// wait 2 seconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(10000);

// read the GPS value
delay(2000);

float latitude, longitude, speed_kph, heading, speed_mph, altitude;

// if you ask for an altitude reading, getGPS will return false if there isn’t a 3D fix
boolean gps_success = fona.getGPS(&latitude, &longitude, &speed_kph, &heading, &altitude);

if (gps_success) {

Serial.print(“GPS lat:”);
Serial.println(latitude, 6);
Serial.print(“GPS long:”);
Serial.println(longitude, 6);
//    Serial.print(“GPS speed KPH:”);
//  Serial.println(speed_kph);
//Serial.print(“GPS speed MPH:”);
//    speed_mph = speed_kph * 0.621371192;
//  Serial.println(speed_mph);
Serial.print(“GPS heading:”);
Serial.println(heading);
Serial.print(“GPS altitude:”);
Serial.println(altitude);

} else {
Serial.println(“Waiting for FONA GPS 3D fix…”);
}

// print the results to the serial monitor:

messageString = label + outputValue + label2 + fona.getGPS(&latitude, &longitude, &speed_kph, &heading, &altitude); //HOW DO I GET GPS DATA IN HERE?
messageString.toCharArray(message, 141);
if (outputValue > threshold){
//Send an automatic response
Serial.println(“Threshold exceeded, sending reponse…”);
if (!fona.sendSMS(sendto, message)) {
Serial.println(F(“Failed”));
} else {
Serial.println(F(“Sent!”));
}
}

// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(2);
}