JSONdemo.ino
1 // SPDX-FileCopyrightText: 2014 Benoit Blanchon 2 // SPDX-FileCopyrightText: 2014 Arturo Guadalupi 3 // SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries 4 // 5 // SPDX-License-Identifier: MIT 6 7 /* 8 This example creates a client object that connects and transfers 9 data using always SSL, then shows how to parse a JSON document in an HTTP response. 10 11 It is compatible with the methods normally related to plain 12 connections, like client.connect(host, port). 13 14 Written by Arturo Guadalupi + Copyright Benoit Blanchon 2014-2019 15 last revision November 2015 16 17 */ 18 19 #include <WiFiClientSecure.h> 20 #include <ArduinoJson.h> 21 #include <Wire.h> 22 23 // uncomment the next line if you have a 128x32 OLED on the I2C pins 24 //#define USE_OLED 25 // uncomment the next line to deep sleep between requests 26 //#define USE_DEEPSLEEP 27 28 #if defined(USE_OLED) 29 // Some boards have TWO I2C ports, how nifty. We should use the second one sometimes 30 #if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \ 31 defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \ 32 defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) 33 #define OLED_I2C_PORT &Wire1 34 #else 35 #define OLED_I2C_PORT &Wire 36 #endif 37 38 #include <Adafruit_SSD1306.h> 39 Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, OLED_I2C_PORT); 40 #endif 41 42 // Enter your WiFi SSID and password 43 char ssid[] = "YOUR_SSID"; // your network SSID (name) 44 char pass[] = "YOUR_SSID_PASSWORD"; // your network password (use for WPA, or use as key for WEP) 45 int keyIndex = 0; // your network key Index number (needed only for WEP) 46 47 48 int status = WL_IDLE_STATUS; 49 // if you don't want to use DNS (and reduce your sketch size) 50 // use the numeric IP instead of the name for the server: 51 //IPAddress server(74,125,232,128); // numeric IP for Google (no DNS) 52 53 #define SERVER "cdn.syndication.twimg.com" 54 #define PATH "/widgets/followbutton/info.json?screen_names=adafruit" 55 56 57 void setup() { 58 //Initialize serial and wait for port to open: 59 Serial.begin(115200); 60 61 // Connect to WPA/WPA2 network 62 WiFi.begin(ssid, pass); 63 64 #if defined(USE_OLED) 65 setupI2C(); 66 delay(200); // wait for OLED to reset 67 68 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32 69 Serial.println(F("SSD1306 allocation failed")); 70 for(;;); // Don't proceed, loop forever 71 } 72 display.display(); 73 display.setTextSize(1); 74 display.setTextColor(WHITE); 75 display.clearDisplay(); 76 display.setCursor(0,0); 77 #else 78 // Don't wait for serial if we have an OLED 79 while (!Serial) { 80 // wait for serial port to connect. Needed for native USB port only 81 delay(10); 82 } 83 #endif 84 // attempt to connect to Wifi network: 85 Serial.print("Attempting to connect to SSID: "); 86 Serial.println(ssid); 87 #if defined(USE_OLED) 88 display.clearDisplay(); display.setCursor(0,0); 89 display.print("Connecting to SSID\n"); display.println(ssid); 90 display.display(); 91 #endif 92 93 94 while (WiFi.status() != WL_CONNECTED) { 95 delay(500); 96 Serial.print("."); 97 } 98 99 Serial.println(""); 100 Serial.println("Connected to WiFi"); 101 102 #if defined(USE_OLED) 103 display.print("...OK!"); 104 display.display(); 105 #endif 106 107 printWifiStatus(); 108 } 109 110 uint32_t bytes = 0; 111 112 void loop() { 113 WiFiClientSecure client; 114 client.setInsecure(); // don't use a root cert 115 116 Serial.println("\nStarting connection to server..."); 117 #if defined(USE_OLED) 118 display.clearDisplay(); display.setCursor(0,0); 119 display.print("Connecting to "); display.print(SERVER); 120 display.display(); 121 #endif 122 123 // if you get a connection, report back via serial: 124 if (client.connect(SERVER, 443)) { 125 Serial.println("connected to server"); 126 // Make a HTTP request: 127 client.println("GET " PATH " HTTP/1.1"); 128 client.println("Host: " SERVER); 129 client.println("Connection: close"); 130 client.println(); 131 } 132 133 // Check HTTP status 134 char status[32] = {0}; 135 client.readBytesUntil('\r', status, sizeof(status)); 136 if (strcmp(status, "HTTP/1.1 200 OK") != 0) { 137 Serial.print(F("Unexpected response: ")); 138 Serial.println(status); 139 #if defined(USE_OLED) 140 display.print("Connection failed, code: "); display.println(status); 141 display.display(); 142 #endif 143 144 return; 145 } 146 147 // wait until we get a double blank line 148 client.find("\r\n\r\n", 4); 149 150 // Allocate the JSON document 151 // Use arduinojson.org/v6/assistant to compute the capacity. 152 const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(8) + 200; 153 DynamicJsonDocument doc(capacity); 154 155 // Parse JSON object 156 DeserializationError error = deserializeJson(doc, client); 157 if (error) { 158 Serial.print(F("deserializeJson() failed: ")); 159 Serial.println(error.c_str()); 160 return; 161 } 162 163 // Extract values 164 JsonObject root_0 = doc[0]; 165 Serial.println(F("Response:")); 166 const char* root_0_screen_name = root_0["screen_name"]; 167 long root_0_followers_count = root_0["followers_count"]; 168 169 Serial.print("Twitter username: "); Serial.println(root_0_screen_name); 170 Serial.print("Twitter followers: "); Serial.println(root_0_followers_count); 171 #if defined(USE_OLED) 172 display.clearDisplay(); display.setCursor(0,0); 173 display.setTextSize(2); 174 display.println(root_0_screen_name); 175 display.println(root_0_followers_count); 176 display.display(); 177 display.setTextSize(1); 178 #endif 179 180 // Disconnect 181 client.stop(); 182 delay(1000); 183 184 #if defined(USE_DEEPSLEEP) 185 #if defined(USE_OLED) 186 display.clearDisplay(); 187 display.display(); 188 #endif // OLED 189 #if defined(NEOPIXEL_POWER) 190 digitalWrite(NEOPIXEL_POWER, LOW); // off 191 #elif defined(NEOPIXEL_I2C_POWER) 192 digitalWrite(NEOPIXEL_I2C_POWER, LOW); // off 193 #endif 194 // wake up 1 second later and then go into deep sleep 195 esp_sleep_enable_timer_wakeup(10 * 1000UL * 1000UL); // 10 sec 196 esp_deep_sleep_start(); 197 #else 198 delay(10 * 1000); 199 #endif 200 } 201 202 void setupI2C() { 203 #if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \ 204 defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \ 205 defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) 206 // ESP32 is kinda odd in that secondary ports must be manually 207 // assigned their pins with setPins()! 208 Wire1.setPins(SDA1, SCL1); 209 #endif 210 211 #if defined(NEOPIXEL_I2C_POWER) 212 pinMode(NEOPIXEL_I2C_POWER, OUTPUT); 213 digitalWrite(NEOPIXEL_I2C_POWER, HIGH); // on 214 #endif 215 216 #if defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2) 217 // turn on the I2C power by setting pin to opposite of 'rest state' 218 pinMode(PIN_I2C_POWER, INPUT); 219 delay(1); 220 bool polarity = digitalRead(PIN_I2C_POWER); 221 pinMode(PIN_I2C_POWER, OUTPUT); 222 digitalWrite(PIN_I2C_POWER, !polarity); 223 #endif 224 } 225 226 void printWifiStatus() { 227 // print the SSID of the network you're attached to: 228 Serial.print("SSID: "); 229 Serial.println(WiFi.SSID()); 230 231 // print your board's IP address: 232 IPAddress ip = WiFi.localIP(); 233 Serial.print("IP Address: "); 234 Serial.println(ip); 235 236 // print the received signal strength: 237 long rssi = WiFi.RSSI(); 238 Serial.print("signal strength (RSSI):"); 239 Serial.print(rssi); 240 Serial.println(" dBm"); 241 }