86e610154efdc9bbfcb870b795d9a2232f0f140c
[iotcloud.git] / version2 / src / C / Sensor-Arduino.ino
1 #include "Table.h"
2 #include "IoTString.h"
3 #include "TimingSingleton.h"
4 #include "TransactionStatus.h"
5 #include "DHT.h"
6
7 SYSTEM_MODE(SEMI_AUTOMATIC)
8 SYSTEM_THREAD(ENABLED)
9
10 // System defines
11 // Arduino
12 #define DHTPIN                          2               // Data pin
13 #define PWRPIN                          D5              // Power pin
14 #define ERRPIN                          D7              // Error pin
15 #define DHTTYPE                         DHT22   // DHT 22  (AM2302)
16 // IoTCloud
17 #define SLEEP_TIME                      300             // Sleep time in seconds
18 #define RETRY_SLEEP_TIME        15              // Sleep time in seconds
19 #define RETRY_TIME                      10000   // stop trying after 10 seconds
20 #define CONNECTION_DELAY        2100000 // Need to delay after connecting WiFi to wait for sensor
21
22 // Initialize DHT sensor for normal 16mhz Arduino
23 DHT dht(DHTPIN, DHTTYPE);
24
25 // Globals
26 // IoTCloud
27 TimingSingleton *timer;
28 bool foundError;
29 MyVector<TransactionStatus *> * transStatusList;
30 char keyBuffer[80];
31 char dataBuffer[80];
32 Table *t1;
33 int64_t machineId;
34
35 void setup() {
36         // TODO: 
37         // 1) Before running PHOTON's with this firmware,
38         //    please go to the master branch and run Init.C
39         //    in iotcloud/version2/src/C to initialize 
40         //    a table on the cloud side.
41         //    If you want to read the committed keys and values 
42         //    on the cloud, then you can use Read.java in
43         //    iotcloud/version2/src/java/simple_test.
44         // 2) If you want to use the Serial library, 
45         //    please install "screen" on your machine and run
46         //    it on the serial port right after flashing the
47         //    firmware onto the Particle board.
48         //    e.g. sudo screen /dev/ttyACM0
49
50         // We use one I/O pin to power the sensor so
51         // that we can make it go to sleep when we go into
52         // deep sleep.
53         
54         // TODO: Profiling!
55         //Serial.begin();
56         //Serial.print("Time begin setup: ");
57         //Serial.println(micros());
58         // Turn on sensor
59         pinMode(PWRPIN, OUTPUT);
60         digitalWrite(PWRPIN, HIGH);
61         // Arduino DHT
62         dht.begin();
63         // Connect to WiFi and Particle cloud
64         // Wait for a maximum amount of time - sleep if WiFi is not connected
65         // Wake up and try again afterwards
66         // TODO: either use this or just WiFi connection (below)
67         //Particle.connect();
68         //if (!waitFor(Particle.connected, RETRY_TIME))
69         //      System.sleep(SLEEP_MODE_DEEP, RETRY_SLEEP_TIME);
70
71         // Connect only to WiFi
72         WiFi.on();
73         WiFi.connect();
74         if (!waitFor(WiFi.ready, RETRY_TIME))
75                 System.sleep(SLEEP_MODE_DEEP, RETRY_SLEEP_TIME);
76         // Check if we already got an IP from the router
77         while(WiFi.localIP().toString().equals("0.0.0.0")) { }
78         // Add delay if needed (for the humidity sensor we need ~2s delay)
79         if (micros() < CONNECTION_DELAY)
80                 // Delays are in millis but micros() returns microsecond time
81                 delay((CONNECTION_DELAY - micros())/1000);
82
83         // TODO: Profiling WiFi
84         //Serial.println(micros());
85         //while(true) { }
86
87         // Prepare device key from MAC (just last 2 of 6 digits)
88         byte mac[6];
89         WiFi.macAddress(mac);
90
91         // TODO: Uncomment the following block to print MAC
92         //for (int i=0; i<6; i++) {
93         //      Serial.printf("%02x%s", mac[i], i != 5 ? ":" : "");
94         //}
95         //Serial.println();
96         // Prepare machine ID
97         int64_t mac4 = (int64_t) mac[4];
98         int64_t mac5 = (int64_t) mac[5];
99         machineId = (mac4 * 256) +  mac5;
100         
101         // IoTCloud library
102         timer = TimingSingleton_getInstance();
103         foundError = false;
104         transStatusList = new MyVector<TransactionStatus *>();
105         IoTString *baseurl = new IoTString("http://dc-6.calit2.uci.edu/test.iotcloud/");
106         IoTString *password = new IoTString("reallysecret");
107         //Serial.print("Time begin rebuilding table: ");
108         //Serial.println(micros());     
109         
110         t1 = new Table(baseurl, password, machineId, -1);
111         t1->rebuild();
112
113         baseurl->releaseRef();
114         password->releaseRef();
115         
116         //Serial.print("Time end setup: ");
117         //Serial.println(micros());
118 }
119
120 void loop() {
121         // Wait until sensor is ready
122         //delay(2000);
123         //Serial.print("Time begin loop: ");
124         //Serial.println(micros());
125         // Read humidity
126         float humid = dht.readHumidity();
127         // Read temperature as Fahrenheit
128         float tempF = dht.readTemperature(true);
129         // Check if any reads failed and exit early (to try again).
130         if (isnan(tempF))
131                 return;
132         // Humidity
133         // Key
134         sprintf(keyBuffer, "humid%d", machineId);
135         IoTString * iKeyHumid = new IoTString(keyBuffer);
136         // Do updates for the temperature
137         sprintf(dataBuffer, "%f", humid);
138         IoTString * iValueHumid = new IoTString(dataBuffer);
139
140         // Check and create a new key if it isn't created yet
141         t1->createNewKey(iKeyHumid, machineId);
142         t1->startTransaction();
143         t1->put(iKeyHumid, iValueHumid);
144         transStatusList->add(t1->commitTransaction());
145
146         // Temperature
147         // Key
148         sprintf(keyBuffer, "tempF%d", machineId);
149         IoTString * iKeyTempF = new IoTString(keyBuffer);
150         // Do updates for the temperature
151         sprintf(dataBuffer, "%f", tempF);
152         IoTString * iValueTempF = new IoTString(dataBuffer);
153
154         // Check and create a new key if it isn't created yet
155         t1->createNewKey(iKeyTempF, machineId);
156         t1->startTransaction();
157         t1->put(iKeyTempF, iValueTempF);
158         transStatusList->add(t1->commitTransaction());
159         t1->update();
160
161         iKeyHumid->releaseRef();
162         iValueHumid->releaseRef();
163         iKeyTempF->releaseRef();
164         iValueTempF->releaseRef();
165         
166         for (uint i = 0; i < transStatusList->size(); i++) {
167                 TransactionStatus * status = transStatusList->get(i);
168                 if (status->getStatus() != TransactionStatus_StatusCommitted) {
169                         foundError = true;
170                         digitalWrite(ERRPIN, HIGH);     // Turn on LED upon error
171                 }
172                 delete status;
173         }
174         
175         // Turn off sensor
176         digitalWrite(PWRPIN, LOW);
177
178         // TODO: Profiling!
179         //Serial.print("Time end loop: ");
180         //Serial.println(micros());
181         //while(true) { }
182         System.sleep(SLEEP_MODE_DEEP, SLEEP_TIME);
183 }
184