-
Notifications
You must be signed in to change notification settings - Fork 0
/
Initial-Test.ino
218 lines (198 loc) · 7.21 KB
/
Initial-Test.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// This code was written by Bill Lovegrove and was modified by Numan Jan to include changes for the Huzzah!
// Reads OBD-II data via a Sparkfun OBD-II_UART board,
// Transmits the data to the Microsoft Azure IoT hub
#include <SPI.h>
#include <WiFi101.h>
#include <stdlib.h>
const int LED = 6 ;
char ssid[] = "*****"; // Wifi usr
char pass[] = "*****"; // wifi pw
// Azure IoTHub details
char hostname[] = "fluuffy.azure-devices.net";
char feeduri[] = "/devices/CarSmart/messages/events?api-version=2016-06-08";
char authSAS[] = "***";
char message[] = "{ \"Seq\":\"0000\", \"DeviceID\":\"CarSmart\", \"Month\":\"3\", \"Temp\":\"+000\" }";
int sequence_num = 0;
const int seq_offset = 9; // offset in message to place sequence number
const int temp_offset = 60; // offset to place temp, sign then three digits
int engineTemp = 65; // Starting engine temp, around room temp for testing
int engineTempF = 0; // temp converted to degrees F
char rxData[30]; // OBD receive buffer was 20; increased buffer size
char rxIndex = 0;
// Details for IoTHub access
unsigned long lastConnectionTime = 0;
const unsigned long uploadInterval = 20000L; // 20 sec delay between uploads
int status = WL_IDLE_STATUS;
WiFiSSLClient client;
void setup() {
// USB Serial port setup for debugging
delay(300); //changed delay from 500ms -> 300ms
Serial.println();
Serial.println("Setup.");
pinMode(LED, OUTPUT); // LED pin direction
// External serial port to OBD
Serial1.begin(9600);
Serial1.println("ATZ"); // Reset the OBD
delay(500); // 1 s delay was too slow. Changed to 0.5 s
getResponse(); // Get the echo
Serial.println(rxData);
getResponse(); // Get the blsnk lines
getResponse(); // Get the blsnk lines
getResponse(); // Get the response
Serial.print("ATZ Response ");
Serial.println(rxData);
getResponse(); // Get the blsnk lines
Serial1.println("ATSP0"); // Auto detect protocol
delay(250); //delay reduced to half
getResponse(); // Get the echo
Serial.println(rxData);
getResponse(); // Get the response
Serial.print("ATSP0 Response ");
Serial.println(rxData);
getResponse(); // Get the blsnk line
processODB();
//check for the presence of wifi
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("No Wifi found.");
// Fast blink to indicate error
while (true) {
// Fast blink if no shield
digitalWrite(LED, HIGH);
delay(125);
digitalWrite(LED, LOW);
delay(125);
}
}
Serial.println("Found Wifi Interface");
Serial1.flush(); // Flush ODB input port
// attempt to connect to Wifi network:
while (status != WL_CONNECTED) {
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection, brief blink
Serial.println("Attempting to connect to Lovegrove Wifi..."); //Kept Bill's print here because he wrote awesome code
digitalWrite(LED, HIGH);
delay(125);
digitalWrite(LED, LOW);
delay(10000);
}
Serial.println("Connected to Lovegrove Wifi");
}
void loop()
{
String response = "";
char c;
///Check for incoming responses
while (client.available()) {
c = client.read();
response.concat(c);
}
if (!response.equals(""))
{
if (response.startsWith("HTTP/1.1 204"))
{
Serial.println("No messages");
}
else
{
// Azure error response messages will be received and printed here
Serial.print("Response: ");
Serial.println(response);
}
}
// After uploadInterval, do a new transmission
if (millis() - lastConnectionTime > uploadInterval) {
processODB();
Serial.println("transmitting");
digitalWrite(LED, LOW);
azureHttpPost();
}
}
// this method makes an HTTPS post to the IoTHub
void azureHttpPost() {
client.stop();
if (client.connect(hostname, 443)) {
// Increment the sequence number and insert into message
sequence_num = sequence_num + 1;
message[seq_offset] = sequence_num/1000 + '0';
message[seq_offset+1] = (sequence_num%1000)/100 + '0';
message[seq_offset+2] = (sequence_num%100)/10 + '0';
message[seq_offset+3] = (sequence_num%10) + '0';
// Insert engineTemp into message
engineTempF = ((engineTemp-40)*9)/5 + 32;
Serial.print("Engine temp (F): ");
Serial.println((engineTempF));
message[temp_offset] = (engineTempF<0) ? '-' : '+';
message[temp_offset+1] = abs(engineTempF)/100 + '0';
message[temp_offset+2] = (abs(engineTempF)%100)/10 + '0';
message[temp_offset+3] = abs(engineTempF)%10 + '0';
//make the POST request to the Azure IOT device port
client.print("POST "); //Do a POST
client.print(feeduri);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(hostname);
client.print("Authorization: ");
client.println(authSAS);
client.println("ContentType: application/json");
client.print("Content-Length: ");
client.println(sizeof(message));
Serial.println(sizeof(message)); // message to serial port for debugging
Serial.println(message);
client.println(); // must have blank line to end header
client.print(message);
client.println();
// time for updateInterval comparison
lastConnectionTime = millis();
}
else {
Serial.println("connection failed");
}
}
// The getResponse function collects incoming data from the UART into the rxData buffer
// and only exits when a carriage return character is seen. Once the carriage return
// string is detected, the rxData buffer is null terminated (so we can treat it as a string)
// and the rxData index is reset to 0 so that the next string can be copied.
// This function was copied and modified with permission from the Sparkfun.com tutorial, copyright CC BY-NC-SA 3/0
// http://creativecommons.org/licenses/by-nc-sa/3.0/
void getResponse(void){
char inChar=0;
//Keep reading characters until we get a carriage return
while(inChar != '\r'){
//If a character comes in on the serial port, we need to act on it.
if(Serial1.available() > 0){
//Start by checking if we've received the end of message character ('\r').
if(Serial1.peek() == '\r'){
//Clear the Serial buffer
inChar=Serial1.read();
//Put the end of string character on our data string
rxData[rxIndex]='\0';
//Reset the buffer index so that the next character goes back at the beginning of the string.
rxIndex=0;
}
//If we didn't get the end of message character, just add the new character to the string.
else{
//Get the new character from the Serial port.
inChar = Serial1.read();
//Add the new character to the string, and increment the index variable.
rxData[rxIndex++]=inChar;
}
}
}
}
// Read and process the ODB Data
void processODB() {
Serial.println("processODB");
Serial1.println("0105"); // Request engine coolant
getResponse(); // Get the echo
Serial.print("OBD Echo: ");
Serial.println(rxData);
getResponse(); // Get the SEARCING
Serial.print("OBD Response1: ");
Serial.println(rxData);
getResponse(); // Get the real response
Serial.print("OBD Response 2: ");
Serial.println(rxData);
engineTemp = strtol(&rxData[6],0,16);
Serial.print("Engine temp: ");
Serial.println(engineTemp);
}