├── .gitattributes └── DIY_Knocki └── DIY_Knocki.ino /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /DIY_Knocki/DIY_Knocki.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Code for DIY Knocki 3 | a project made by Sachin Soni for his YouTube Channel named "techiesms" 4 | 5 | Originally from Steve Hoefer http://grathio.com Version 0.1.10.20.10 6 | Updates by Lee Sonko 7 | 8 | Licensed under Creative Commons Attribution-Noncommercial-Share Alike 3.0 9 | http://creativecommons.org/licenses/by-nc-sa/3.0/us/ 10 | (In short: Do what you want, just be sure to include this line and the four above it, and don't sell it or use it in anything you sell without contacting me.) 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | ESP8266WiFiMulti WiFiMulti; 18 | 19 | // Pin definitions 20 | #define Green D4 // for green LED 21 | #define Red D5 // for red LED 22 | #define knockSensor A0 // for accelerometer 23 | 24 | String Webhooks_key = "Your Webhooks' Key"; 25 | 26 | void Knock1_Action(String Event_name); 27 | void Knock2_Action(String Event_name); 28 | void Knock3_Action(String Event_name); 29 | void Knock4_Action(String Event_name); 30 | void Knock5_Action(String Event_name); 31 | void Knock6_Action(String Event_name); 32 | 33 | 34 | int threshold = 0; // Minimum signal from the accelerometer to register as a knock 35 | 36 | // Tuning constants. 37 | const int rejectValue = 25; // If an individual knock is off by this percentage of a knock we don't recognize. 38 | const int averageRejectValue = 15; // If the average timing of the knocks is off by this percent we don't recognize. 39 | const int knockFadeTime = 150; // milliseconds we allow a knock to fade before we listen for another one. (Debounce timer.) 40 | 41 | const int maximumKnocks = 20; // Maximum number of knocks to listen for. 42 | const int knockComplete = 1200; // Longest time to wait for a knock before we assume that it's finished. 43 | 44 | // Stored Knock Patterns 45 | int secretCode1[maximumKnocks] = {100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // .. 46 | int secretCode2[maximumKnocks] = {100, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ... 47 | int secretCode3[maximumKnocks] = {75, 20, 100, 72, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // . .. . .. 48 | int secretCode4[maximumKnocks] = {25, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // .. . 49 | int secretCode5[maximumKnocks] = {29, 100, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // .. .. 50 | 51 | 52 | int knockReadings[maximumKnocks]; // When someone knocks this array fills with delays between knocks. 53 | int knockSensorValue = 0; // Last reading of the knock sensor. 54 | int programButtonPressed = false; // Flag so we remember the programming button setting at the end of the cycle. 55 | 56 | 57 | void setup() 58 | { 59 | 60 | pinMode(Red, OUTPUT); 61 | pinMode(Green, OUTPUT); 62 | digitalWrite(Red, LOW); 63 | digitalWrite(Green, LOW); 64 | 65 | //---------------------------------- Logic for calibration of surface 66 | digitalWrite(Red, HIGH); 67 | 68 | Serial.begin(115200); 69 | 70 | // Connect to WiFi network 71 | for (uint8_t t = 4; t > 0; t--) 72 | { 73 | Serial.printf("[SETUP] WAIT %d...\n", t); 74 | Serial.flush(); 75 | delay(1000); 76 | } 77 | 78 | for (int c = 0; c <= 20 ; c++) 79 | { 80 | int thresho = analogRead(knockSensor); 81 | threshold = thresho + threshold; 82 | delay(10); 83 | } 84 | 85 | threshold = (threshold / 20) - 2; 86 | 87 | Serial.print("Thresold Value is : "); Serial.println(threshold); 88 | 89 | digitalWrite(Red, LOW); 90 | digitalWrite(Green, HIGH); 91 | delay(500); 92 | digitalWrite(Green, LOW); 93 | 94 | WiFi.mode(WIFI_STA); 95 | WiFiMulti.addAP("SSID", "PASS"); 96 | WiFiMulti.addAP("SSID", "PASS"); 97 | Serial.println("Program start."); 98 | 99 | } 100 | 101 | void loop() 102 | { 103 | while (WiFiMulti.run() != WL_CONNECTED) 104 | { 105 | Serial.println("WiFi not Connected."); 106 | delay(100); 107 | } 108 | 109 | // Listen for any knock at all. 110 | knockSensorValue = analogRead(knockSensor); 111 | 112 | if (knockSensorValue >= threshold) 113 | { 114 | listenToSecretKnock(); 115 | } 116 | } 117 | 118 | // Records the timing of knocks. 119 | void listenToSecretKnock() 120 | { 121 | Serial.println("knock starting"); 122 | int i = 0; 123 | // First lets reset the listening array. 124 | for (i = 0; i < maximumKnocks; i++) 125 | { 126 | knockReadings[i] = 0; 127 | } 128 | 129 | int currentKnockNumber = 0; // Incrementer for the array. 130 | int startTime = millis(); // Reference for when this knock started. 131 | int now = millis(); 132 | 133 | delay(knockFadeTime); // wait for this peak to fade before we listen to the next one. 134 | 135 | do 136 | { 137 | //listen for the next knock or wait for it to timeout. 138 | knockSensorValue = analogRead(knockSensor); 139 | 140 | if (knockSensorValue >= threshold) //got another knock... 141 | { 142 | 143 | Serial.println("knock."); 144 | //record the delay time. 145 | now = millis(); 146 | knockReadings[currentKnockNumber] = now - startTime; 147 | currentKnockNumber ++; //increment the counter 148 | startTime = now; 149 | // and reset our timer for the next knock 150 | 151 | delay(knockFadeTime); // again, a little delay to let the knock decay. 152 | 153 | } 154 | now = millis(); 155 | 156 | //did we timeout or run out of knocks? 157 | } while ((now - startTime < knockComplete) && (currentKnockNumber < maximumKnocks)); 158 | 159 | //we've got our knock recorded, lets see if it's valid 160 | if (programButtonPressed == false) // only if we're not in progrmaing mode. 161 | { 162 | if (validateKnock1() == true) 163 | { 164 | Knock1_Action("EVENT_NAME"); 165 | } 166 | else if (validateKnock2() == true) 167 | { 168 | Knock2_Action("EVENT_NAME"); 169 | } 170 | else if (validateKnock3() == true) 171 | { 172 | Knock3_Action("EVENT_NAME"); 173 | } 174 | else if (validateKnock4() == true) 175 | { 176 | Knock4_Action("EVENT_NAME"); 177 | } 178 | else if (validateKnock5() == true) 179 | { 180 | Knock5_Action("EVENT_NAME"); 181 | } 182 | else 183 | { 184 | Serial.println("Secret knock failed."); 185 | for (int i = 0; i < 3; i++) 186 | { 187 | digitalWrite(Red, HIGH); 188 | delay(200); 189 | digitalWrite(Red, LOW); 190 | delay(100); 191 | } 192 | } 193 | } 194 | else 195 | { 196 | 197 | } 198 | 199 | } 200 | 201 | boolean validateKnock1() 202 | { 203 | int i = 0; 204 | 205 | // simplest check first: Did we get the right number of knocks? 206 | int currentKnockCount = 0; 207 | int secretKnockCount = 0; 208 | int maxKnockInterval = 0; // We use this later to normalize the times. 209 | 210 | for (i = 0; i < maximumKnocks; i++) { 211 | if (knockReadings[i] > 0) { 212 | currentKnockCount++; 213 | } 214 | if (secretCode1[i] > 0) { //todo: precalculate this. 215 | secretKnockCount++; 216 | } 217 | 218 | if (knockReadings[i] > maxKnockInterval) { // collect normalization data while we're looping. 219 | maxKnockInterval = knockReadings[i]; 220 | } 221 | } 222 | 223 | // If we're recording a new knock, save the info and get out of here. 224 | if (programButtonPressed == true) { 225 | for (i = 0; i < maximumKnocks; i++) { // normalize the times 226 | secretCode1[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 227 | } 228 | 229 | return false; // We don't unlock the door when we are recording a new knock. 230 | } 231 | 232 | if (currentKnockCount != secretKnockCount) { 233 | return false; 234 | } 235 | 236 | /* Now we compare the relative intervals of our knocks, not the absolute time between them. 237 | (ie: if you do the same pattern slow or fast it should still open the door.) 238 | This makes it less picky, which while making it less secure can also make it 239 | less of a pain to use if your tempo is a little slow or fast. 240 | */ 241 | int totaltimeDifferences = 0; 242 | int timeDiff = 0; 243 | for (i = 0; i < maximumKnocks; i++) { // Normalize the times 244 | knockReadings[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 245 | timeDiff = abs(knockReadings[i] - secretCode1[i]); 246 | if (timeDiff > rejectValue) { // Individual value too far out of whack 247 | return false; 248 | } 249 | totaltimeDifferences += timeDiff; 250 | } 251 | // It can also fail if the whole thing is too inaccurate. 252 | if (totaltimeDifferences / secretKnockCount > averageRejectValue) { 253 | return false; 254 | } 255 | Serial.println("Pattern Matched!!"); 256 | return true; 257 | 258 | } 259 | 260 | boolean validateKnock2() { 261 | int i = 0; 262 | 263 | // simplest check first: Did we get the right number of knocks? 264 | int currentKnockCount = 0; 265 | int secretKnockCount = 0; 266 | int maxKnockInterval = 0; // We use this later to normalize the times. 267 | 268 | for (i = 0; i < maximumKnocks; i++) { 269 | if (knockReadings[i] > 0) { 270 | currentKnockCount++; 271 | } 272 | if (secretCode2[i] > 0) { //todo: precalculate this. 273 | secretKnockCount++; 274 | } 275 | 276 | if (knockReadings[i] > maxKnockInterval) { // collect normalization data while we're looping. 277 | maxKnockInterval = knockReadings[i]; 278 | } 279 | } 280 | 281 | // If we're recording a new knock, save the info and get out of here. 282 | if (programButtonPressed == true) { 283 | for (i = 0; i < maximumKnocks; i++) { // normalize the times 284 | secretCode2[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 285 | } 286 | return false; // We don't unlock the door when we are recording a new knock. 287 | } 288 | 289 | if (currentKnockCount != secretKnockCount) { 290 | return false; 291 | } 292 | 293 | /* Now we compare the relative intervals of our knocks, not the absolute time between them. 294 | (ie: if you do the same pattern slow or fast it should still open the door.) 295 | This makes it less picky, which while making it less secure can also make it 296 | less of a pain to use if your tempo is a little slow or fast. 297 | */ 298 | int totaltimeDifferences = 0; 299 | int timeDiff = 0; 300 | for (i = 0; i < maximumKnocks; i++) { // Normalize the times 301 | knockReadings[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 302 | timeDiff = abs(knockReadings[i] - secretCode2[i]); 303 | if (timeDiff > rejectValue) { // Individual value too far out of whack 304 | return false; 305 | } 306 | totaltimeDifferences += timeDiff; 307 | } 308 | // It can also fail if the whole thing is too inaccurate. 309 | if (totaltimeDifferences / secretKnockCount > averageRejectValue) { 310 | return false; 311 | } 312 | Serial.println("Pattern Matched!!"); 313 | return true; 314 | 315 | } 316 | 317 | boolean validateKnock3() { 318 | int i = 0; 319 | 320 | // simplest check first: Did we get the right number of knocks? 321 | int currentKnockCount = 0; 322 | int secretKnockCount = 0; 323 | int maxKnockInterval = 0; // We use this later to normalize the times. 324 | 325 | for (i = 0; i < maximumKnocks; i++) { 326 | if (knockReadings[i] > 0) { 327 | currentKnockCount++; 328 | } 329 | if (secretCode3[i] > 0) { //todo: precalculate this. 330 | secretKnockCount++; 331 | } 332 | 333 | if (knockReadings[i] > maxKnockInterval) { // collect normalization data while we're looping. 334 | maxKnockInterval = knockReadings[i]; 335 | } 336 | } 337 | 338 | // If we're recording a new knock, save the info and get out of here. 339 | if (programButtonPressed == true) { 340 | for (i = 0; i < maximumKnocks; i++) { // normalize the times 341 | secretCode3[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 342 | } 343 | return false; // We don't unlock the door when we are recording a new knock. 344 | } 345 | 346 | if (currentKnockCount != secretKnockCount) { 347 | return false; 348 | } 349 | 350 | /* Now we compare the relative intervals of our knocks, not the absolute time between them. 351 | (ie: if you do the same pattern slow or fast it should still open the door.) 352 | This makes it less picky, which while making it less secure can also make it 353 | less of a pain to use if your tempo is a little slow or fast. 354 | */ 355 | int totaltimeDifferences = 0; 356 | int timeDiff = 0; 357 | for (i = 0; i < maximumKnocks; i++) { // Normalize the times 358 | knockReadings[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 359 | timeDiff = abs(knockReadings[i] - secretCode3[i]); 360 | if (timeDiff > rejectValue) { // Individual value too far out of whack 361 | return false; 362 | } 363 | totaltimeDifferences += timeDiff; 364 | } 365 | // It can also fail if the whole thing is too inaccurate. 366 | if (totaltimeDifferences / secretKnockCount > averageRejectValue) { 367 | return false; 368 | } 369 | Serial.println("Pattern Matched!!"); 370 | return true; 371 | 372 | } 373 | 374 | boolean validateKnock4() { 375 | int i = 0; 376 | 377 | // simplest check first: Did we get the right number of knocks? 378 | int currentKnockCount = 0; 379 | int secretKnockCount = 0; 380 | int maxKnockInterval = 0; // We use this later to normalize the times. 381 | 382 | for (i = 0; i < maximumKnocks; i++) { 383 | if (knockReadings[i] > 0) { 384 | currentKnockCount++; 385 | } 386 | if (secretCode4[i] > 0) { //todo: precalculate this. 387 | secretKnockCount++; 388 | } 389 | 390 | if (knockReadings[i] > maxKnockInterval) { // collect normalization data while we're looping. 391 | maxKnockInterval = knockReadings[i]; 392 | } 393 | } 394 | 395 | // If we're recording a new knock, save the info and get out of here. 396 | if (programButtonPressed == true) { 397 | for (i = 0; i < maximumKnocks; i++) { // normalize the times 398 | secretCode4[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 399 | } 400 | return false; // We don't unlock the door when we are recording a new knock. 401 | } 402 | 403 | if (currentKnockCount != secretKnockCount) { 404 | return false; 405 | } 406 | 407 | /* Now we compare the relative intervals of our knocks, not the absolute time between them. 408 | (ie: if you do the same pattern slow or fast it should still open the door.) 409 | This makes it less picky, which while making it less secure can also make it 410 | less of a pain to use if your tempo is a little slow or fast. 411 | */ 412 | int totaltimeDifferences = 0; 413 | int timeDiff = 0; 414 | for (i = 0; i < maximumKnocks; i++) { // Normalize the times 415 | knockReadings[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 416 | timeDiff = abs(knockReadings[i] - secretCode4[i]); 417 | if (timeDiff > rejectValue) { // Individual value too far out of whack 418 | return false; 419 | } 420 | totaltimeDifferences += timeDiff; 421 | } 422 | // It can also fail if the whole thing is too inaccurate. 423 | if (totaltimeDifferences / secretKnockCount > averageRejectValue) { 424 | return false; 425 | } 426 | Serial.println("Pattern Matched!!"); 427 | return true; 428 | 429 | } 430 | 431 | 432 | boolean validateKnock5() { 433 | int i = 0; 434 | 435 | // simplest check first: Did we get the right number of knocks? 436 | int currentKnockCount = 0; 437 | int secretKnockCount = 0; 438 | int maxKnockInterval = 0; // We use this later to normalize the times. 439 | 440 | for (i = 0; i < maximumKnocks; i++) { 441 | if (knockReadings[i] > 0) { 442 | currentKnockCount++; 443 | } 444 | if (secretCode5[i] > 0) { //todo: precalculate this. 445 | secretKnockCount++; 446 | } 447 | 448 | if (knockReadings[i] > maxKnockInterval) { // collect normalization data while we're looping. 449 | maxKnockInterval = knockReadings[i]; 450 | } 451 | } 452 | 453 | // If we're recording a new knock, save the info and get out of here. 454 | if (programButtonPressed == true) { 455 | for (i = 0; i < maximumKnocks; i++) { // normalize the times 456 | secretCode5[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 457 | } 458 | return false; // We don't unlock the door when we are recording a new knock. 459 | } 460 | 461 | if (currentKnockCount != secretKnockCount) { 462 | return false; 463 | } 464 | 465 | /* Now we compare the relative intervals of our knocks, not the absolute time between them. 466 | (ie: if you do the same pattern slow or fast it should still open the door.) 467 | This makes it less picky, which while making it less secure can also make it 468 | less of a pain to use if your tempo is a little slow or fast. 469 | */ 470 | int totaltimeDifferences = 0; 471 | int timeDiff = 0; 472 | for (i = 0; i < maximumKnocks; i++) { // Normalize the times 473 | knockReadings[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100); 474 | timeDiff = abs(knockReadings[i] - secretCode5[i]); 475 | if (timeDiff > rejectValue) { // Individual value too far out of whack 476 | return false; 477 | } 478 | totaltimeDifferences += timeDiff; 479 | } 480 | // It can also fail if the whole thing is too inaccurate. 481 | if (totaltimeDifferences / secretKnockCount > averageRejectValue) { 482 | return false; 483 | } 484 | Serial.println("Pattern Matched!!"); 485 | return true; 486 | 487 | } 488 | 489 | 490 | void Knock1_Action(String Event_name) 491 | { 492 | 493 | 494 | digitalWrite(Green, HIGH); 495 | if ((WiFiMulti.run() == WL_CONNECTED)) 496 | { 497 | 498 | HTTPClient http; 499 | Serial.print("[HTTP] begin...\n"); 500 | // configure traged server and url 501 | //http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS 502 | http.begin("http://maker.ifttt.com/trigger/" + Event_name + "/with/key/" + Webhooks_key); //HTTP 503 | 504 | Serial.print("[HTTP] GET...\n"); 505 | // start connection and send HTTP header 506 | int httpCode = http.GET(); 507 | 508 | // httpCode will be negative on error 509 | if (httpCode > 0) { 510 | // HTTP header has been send and Server response header has been handled 511 | Serial.printf("[HTTP] GET... code: %d\n", httpCode); 512 | 513 | // file found at server 514 | if (httpCode == HTTP_CODE_OK) { 515 | String payload = http.getString(); 516 | Serial.println(payload); 517 | } 518 | } else { 519 | Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); 520 | digitalWrite(Green,LOW); 521 | digitalWrite(Red,HIGH); 522 | delay(2000); 523 | digitalWrite(Red,LOW); 524 | } 525 | 526 | http.end(); 527 | } 528 | digitalWrite(Green, LOW); 529 | } 530 | 531 | void Knock2_Action(String Event_name) 532 | { 533 | digitalWrite(Green, HIGH); 534 | if ((WiFiMulti.run() == WL_CONNECTED)) 535 | { 536 | 537 | HTTPClient http; 538 | Serial.print("[HTTP] begin...\n"); 539 | // configure traged server and url 540 | //http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS 541 | http.begin("http://maker.ifttt.com/trigger/" + Event_name + "/with/key/" + Webhooks_key); //HTTP 542 | 543 | Serial.print("[HTTP] GET...\n"); 544 | // start connection and send HTTP header 545 | int httpCode = http.GET(); 546 | 547 | // httpCode will be negative on error 548 | if (httpCode > 0) { 549 | // HTTP header has been send and Server response header has been handled 550 | Serial.printf("[HTTP] GET... code: %d\n", httpCode); 551 | 552 | // file found at server 553 | if (httpCode == HTTP_CODE_OK) { 554 | String payload = http.getString(); 555 | Serial.println(payload); 556 | } 557 | } else { 558 | Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); 559 | digitalWrite(Green,LOW); 560 | digitalWrite(Red,HIGH); 561 | delay(2000); 562 | digitalWrite(Red,LOW); 563 | } 564 | 565 | http.end(); 566 | } 567 | digitalWrite(Green, LOW); 568 | } 569 | 570 | void Knock3_Action(String Event_name) 571 | { 572 | digitalWrite(Green, HIGH); 573 | if ((WiFiMulti.run() == WL_CONNECTED)) 574 | { 575 | 576 | HTTPClient http; 577 | Serial.print("[HTTP] begin...\n"); 578 | // configure traged server and url 579 | //http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS 580 | http.begin("http://maker.ifttt.com/trigger/" + Event_name + "/with/key/" + Webhooks_key); //HTTP 581 | 582 | Serial.print("[HTTP] GET...\n"); 583 | // start connection and send HTTP header 584 | int httpCode = http.GET(); 585 | 586 | // httpCode will be negative on error 587 | if (httpCode > 0) { 588 | // HTTP header has been send and Server response header has been handled 589 | Serial.printf("[HTTP] GET... code: %d\n", httpCode); 590 | 591 | // file found at server 592 | if (httpCode == HTTP_CODE_OK) { 593 | String payload = http.getString(); 594 | Serial.println(payload); 595 | } 596 | } else { 597 | Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); 598 | digitalWrite(Green,LOW); 599 | digitalWrite(Red,HIGH); 600 | delay(2000); 601 | digitalWrite(Red,LOW); 602 | } 603 | 604 | http.end(); 605 | } 606 | digitalWrite(Green, LOW); 607 | } 608 | 609 | void Knock4_Action(String Event_name) 610 | { 611 | digitalWrite(Green, HIGH); 612 | if ((WiFiMulti.run() == WL_CONNECTED)) 613 | { 614 | 615 | HTTPClient http; 616 | Serial.print("[HTTP] begin...\n"); 617 | // configure traged server and url 618 | //http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS 619 | http.begin("http://maker.ifttt.com/trigger/" + Event_name + "/with/key/" + Webhooks_key); //HTTP 620 | 621 | Serial.print("[HTTP] GET...\n"); 622 | // start connection and send HTTP header 623 | int httpCode = http.GET(); 624 | 625 | // httpCode will be negative on error 626 | if (httpCode > 0) { 627 | // HTTP header has been send and Server response header has been handled 628 | Serial.printf("[HTTP] GET... code: %d\n", httpCode); 629 | 630 | // file found at server 631 | if (httpCode == HTTP_CODE_OK) { 632 | String payload = http.getString(); 633 | Serial.println(payload); 634 | } 635 | } else { 636 | Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); 637 | digitalWrite(Green,LOW); 638 | digitalWrite(Red,HIGH); 639 | delay(2000); 640 | digitalWrite(Red,LOW); 641 | 642 | } 643 | 644 | http.end(); 645 | } 646 | digitalWrite(Green, LOW); 647 | } 648 | 649 | void Knock5_Action(String Event_name) 650 | { 651 | 652 | digitalWrite(Green, HIGH); 653 | if ((WiFiMulti.run() == WL_CONNECTED)) { 654 | 655 | HTTPClient http; 656 | Serial.print("[HTTP] begin...\n"); 657 | // configure traged server and url 658 | //http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS 659 | http.begin("http://maker.ifttt.com/trigger/" + Event_name + "/with/key/" + Webhooks_key); //HTTP 660 | Serial.print("[HTTP] GET...\n"); 661 | // start connection and send HTTP header 662 | int httpCode = http.GET(); 663 | 664 | // httpCode will be negative on error 665 | if (httpCode > 0) { 666 | // HTTP header has been send and Server response header has been handled 667 | Serial.printf("[HTTP] GET... code: %d\n", httpCode); 668 | 669 | // file found at server 670 | if (httpCode == HTTP_CODE_OK) { 671 | String payload = http.getString(); 672 | Serial.println(payload); 673 | } 674 | } else { 675 | Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); 676 | digitalWrite(Green,LOW); 677 | digitalWrite(Red,HIGH); 678 | delay(2000); 679 | digitalWrite(Red,LOW); 680 | } 681 | 682 | http.end(); 683 | } 684 | 685 | digitalWrite(Green, LOW); 686 | } 687 | 688 | 689 | --------------------------------------------------------------------------------