Last active
January 28, 2024 11:12
-
-
Save tranchausky/72282bf1a181242a5c411f50b4ba0e1e to your computer and use it in GitHub Desktop.
bt201 + nanoMcu + website
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <SPI.h> | |
| #include <Wire.h> | |
| #include <SoftwareSerial.h> | |
| #include <ESP8266WebServer.h> | |
| #include <ESP8266WiFiMulti.h> | |
| #include <ESP8266WiFi.h> | |
| #include <ESP8266HTTPClient.h> | |
| #include "index.h" | |
| ESP8266WiFiMulti wifiMulti; | |
| const uint32_t connectTimeoutMs = 5000; | |
| #define LED D4 //Led nodeMCU main | |
| const int esp8266RxPin = D5; // RX from ESP8266 connected to D5 | |
| const int esp8266TxPin = D6; // TX from ESP8266 connected to D6 | |
| SoftwareSerial BT201RXTX(esp8266RxPin, esp8266TxPin); | |
| String resultData =""; | |
| int sendOne = 0; | |
| ESP8266WebServer server(80); | |
| void handleRoot() { | |
| String s = webpage; | |
| server.send(200, "text/html", s); | |
| } | |
| void get_data() { | |
| server.send(200, "text/plane", resultData); | |
| } | |
| void writeString(String stringData) { // Used to serially push out a String with Serial.write() | |
| for (int i = 0; i < stringData.length(); i++) { | |
| BT201RXTX.write(stringData[i]); // Push each char 1 by 1 on each loop pass | |
| } | |
| delay(400); | |
| } // end writeString | |
| void set_data() { | |
| resultData = "";//reset result | |
| String act_state = server.arg("state"); | |
| //mute AT+CU01 unmute AT+CU00 | |
| //AT+QA get volumn | |
| switch (act_state.toInt()) { | |
| case 1: | |
| writeString("AT+CM00"); | |
| break; | |
| case 2: | |
| writeString("AT+CD"); | |
| break; | |
| case 3: | |
| writeString("AT+CC"); | |
| break; | |
| case 4: | |
| writeString("AT+CB"); | |
| break; | |
| case 5: | |
| writeString("AT+CE"); | |
| writeString("AT+QA"); //get volumn | |
| break; | |
| case 6: | |
| writeString("AT+CF"); | |
| writeString("AT+QA"); //get volumn | |
| break; | |
| case 7: | |
| writeString("AT+CM08"); // idle | |
| break; | |
| case 8: | |
| writeString("AT+QA"); | |
| break; | |
| case 101: | |
| writeString("AT+RE01");//turn on record function | |
| writeString("AT+RC00");//record mode | |
| break; | |
| case 102: | |
| writeString("AT+RC01"); //start record | |
| break; | |
| case 103: | |
| writeString("AT+RC05"); //stop record | |
| break; | |
| case 104: | |
| writeString("AT+RC02"); //pause/continue record | |
| break; | |
| case 105: | |
| writeString("AT+RC06"); //play the current recording | |
| break; | |
| case 106: | |
| writeString("AT+RC07"); //play the current recording | |
| break; | |
| case 201: | |
| writeString("AT+CM04"); //Select music mode only | |
| break; | |
| default: | |
| // statements | |
| break; | |
| } | |
| Serial.println("Sent " + act_state + " to BT201"); | |
| server.send(200, "text/plane", act_state); | |
| } | |
| void getGeneral(){ | |
| String type = server.arg("type"); | |
| resultData = ""; | |
| if(type !=""){ | |
| if(type == "MP"){ | |
| writeString("AT+MP"); //get 0,1,2 (stop play pause) | |
| } | |
| }else{ | |
| writeString("AT+QA"); //get (volumn) | |
| writeString("AT+QM"); //get mode | |
| writeString("AT+MP"); //get 0,1,2 (stop play pause) | |
| } | |
| server.send(200, "text/plane", "ok"); | |
| } | |
| void setup(void) { | |
| WiFi.persistent(false); | |
| Serial.begin(115200); | |
| delay(10); | |
| BT201RXTX.begin(115200); | |
| delay(10); | |
| pinMode(LED, OUTPUT); | |
| delay(100); | |
| digitalWrite(LED, LOW);//on | |
| WiFi.mode(WIFI_STA); | |
| // Register multi WiFi networks | |
| wifiMulti.addAP("HatDeFAM", "asdfsadf"); | |
| wifiMulti.addAP("threeway", "asdfghjkl"); | |
| wifiMulti.addAP("AndroidAP45b3", "15051991"); | |
| delay(100); | |
| delay(100); | |
| server.on("/", handleRoot); | |
| server.on("/setdata", set_data); | |
| server.on("/getgeneral", getGeneral); | |
| server.on("/getdata", get_data); | |
| server.begin(); | |
| } | |
| void loop(void) { | |
| // Maintain WiFi connection | |
| if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED) { | |
| digitalWrite(LED, HIGH);//off | |
| sendData(); | |
| server.handleClient(); | |
| //delay(10000); | |
| } else { | |
| digitalWrite(LED, LOW);//on | |
| delay(10000);//10s | |
| Serial.println("WiFi not connected!"); | |
| } | |
| while (BT201RXTX.available()) { | |
| char c = BT201RXTX.read(); //gets one byte from serial buffer | |
| Serial.write(c); | |
| resultData += c; //makes the String readString | |
| delay(3); //slow looping to allow buffer to fill with next character | |
| } | |
| if (Serial.available()) { | |
| String command = Serial.readString(); // Read command from serial monitor | |
| if (command == "c") { | |
| //Serial1.write('QM+03'); | |
| writeString("AT+CM00"); | |
| Serial.println("Sent 'QM+03' to BT201"); | |
| } else if (command == "z") { | |
| Serial.println(WiFi.localIP()); | |
| } else if (command == "p") { | |
| // Send 'p' to play music | |
| //Serial1.write('QM+01'); | |
| writeString("AT+CB"); | |
| Serial.println("Sent 'QM+01' to BT201"); | |
| } else if (command == "s") { | |
| // Send 's' to pause music | |
| //Serial1.write('s'); | |
| writeString("AT+CB"); | |
| Serial.println("Sent 's' to BT201: Pause"); | |
| } else { | |
| // Invalid command | |
| writeString(command); | |
| Serial.println("send command " + command); | |
| } | |
| } | |
| //delay(10); | |
| } | |
| void sendData() { | |
| if (sendOne == 0) { | |
| String hostLink = "https://wwww.com"; | |
| String apiKeyValue = "tPmAT5Ab3j7F9"; | |
| // Use WiFiClient class to create TCP connections | |
| WiFiClientSecure client; | |
| client.setInsecure(); // this is the magical line that makes everything work | |
| // We now create a URI for the request | |
| String url = hostLink + "/track_on/post-esp-data.php"; | |
| String sensorName = "ESP-Audio-BT201"; | |
| String sensorLocation = ""; | |
| String a1 = "on"; | |
| String a2 = ""; | |
| String a3 = ""; | |
| String nameWifi = String(WiFi.SSID()); | |
| String nameIp = WiFi.localIP().toString(); | |
| String datarequest = "api_key=" + apiKeyValue + "&sensor=" + sensorName | |
| + "&location=" + sensorLocation + "&value1=" + a1 | |
| + "&value2=" + a2 + "&value3=" + a3 + "&wifi=" + nameWifi + "&ip=" + nameIp + ""; | |
| Serial.print("Url: "); | |
| Serial.println(url); | |
| Serial.print("httpRequestData: "); | |
| Serial.println(datarequest); | |
| HTTPClient httpre; | |
| httpre.begin(client, url); | |
| httpre.addHeader("Content-Type", "application/x-www-form-urlencoded"); | |
| int httpCode = httpre.POST(datarequest); | |
| String payload = httpre.getString(); | |
| Serial.println(httpCode); | |
| Serial.println(payload); | |
| httpre.end(); | |
| Serial.println("closing connection"); | |
| sendOne = 1; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const char webpage[] PROGMEM = R"=====( | |
| <!DOCTYPE html> | |
| <html> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <style type="text/css"> | |
| .button { | |
| background-color: #4CAF50; | |
| border: none; | |
| color: white; | |
| padding: 9px 28px; | |
| text-align: center; | |
| text-decoration: none; | |
| display: inline-block; | |
| font-size: 16px; | |
| margin-top: 8px; | |
| }.button:hover{color:black;cursor: pointer;box-shadow: rgba(6, 24, 44, 0.4) 0px 0px 0px 2px, rgba(6, 24, 44, 0.65) 0px 4px 6px -1px, rgba(255, 255, 255, 0.08) 0px 1px 0px inset;} | |
| .button:disabled{background-color: #cccccc; color: #666666;} | |
| .select{padding: 8px; font-size: 16px;} | |
| #main{max-width: 611px; margin: auto;} | |
| .d-none{display: none;} | |
| @media only screen and (max-width: 600px) { | |
| .button, .select { | |
| padding: 5px 8px;font-size: 13px; | |
| }.select{padding: 4px 8px;} | |
| } | |
| </style> | |
| <body style="background-color: #f9e79f "> | |
| <center> | |
| <div style="max-width: 900px;"> | |
| <div><h2>Control the audio BT201</h2></div> | |
| <div style="text-align:right;"> | |
| <select class="select" id="typeaudio" disabled> | |
| <option value="" data-view="">Null</option> | |
| <option value="0" data-view="00">Empty mode</option> | |
| <option value="1" data-view="01">Bluetooth</option> | |
| <option value="2" data-view="02">USB</option> | |
| <option value="3" data-view="03">TF</option> | |
| <option value="4" data-view="04">SPIFLASH Play</option> | |
| <option value="5" data-view="05">AUX External</option> | |
| <option value="6" data-view="06">PC sound card</option> | |
| <option value="7" data-view="07">FM Radio</option> | |
| <option value="8" data-view="08">REC recording mode</option> | |
| <option value="9" data-view="09">idle mode</option> | |
| <option value="4">Record</option> | |
| <option value="5">Different</option> | |
| </select> | |
| <button class="button d-none" onclick="send('7')">Off/On</button> | |
| </div> | |
| <div style=" "> | |
| <button class="button" onclick="send('1');viewStatus('00');">Mode</button> | |
| <button class="button" onclick="send('5')">+</button> | |
| <button class="button" onclick="send('6')">-</button> | |
| <button class="button" id="viewvolumn" disabled>--</button> | |
| </div> | |
| <div style=" "> | |
| <button class="button" onclick="send('201')">Music Mode</button> | |
| <button class="button" onclick="send('2')">Back</button> | |
| <button class="button" onclick="send('3')">Next</button> | |
| <button class="button" onclick="send('4');getGeneral('MP');">Pause/Play</button> | |
| <button class="button" id="viewstatus" disabled>--</button> | |
| </div> | |
| <div style=" "> | |
| <button class="button" onclick="send('101')">Record Mode</button> | |
| <button class="button" onclick="send('102')">Record</button> | |
| <button class="button" onclick="send('103')">Stop</button> | |
| <button class="button" onclick="send('104')">Pause/Continue Record</button> | |
| <button class="button" onclick="send('105')">Play Record</button> | |
| <button class="button" onclick="send('106')">Delete Record</button> | |
| </div> | |
| <div> | |
| <button class="button" onclick="send('8')">Test</button> | |
| </div> | |
| <br> | |
| <div><h2> | |
| Action: <span id="state">NA</span> | |
| </h2> | |
| <div style="display: inline-flex;"> | |
| Rezult: | |
| <textarea id="adc_val" rows="9" cols="50" disabled style="width: 100%;"></textarea> | |
| </div> | |
| </div> | |
| <script> | |
| var delay = ( function() { | |
| var timer = 0; | |
| return function(callback, ms) { | |
| clearTimeout (timer); | |
| timer = setTimeout(callback, ms); | |
| }; | |
| })(); | |
| function send(led_sts) | |
| { | |
| var xhttp = new XMLHttpRequest(); | |
| xhttp.onreadystatechange = function() { | |
| if (this.readyState == 4 && this.status == 200) { | |
| document.getElementById("state").innerHTML = this.responseText; | |
| delay(function(){ | |
| getData() | |
| }, 1500); // end delay | |
| } | |
| }; | |
| xhttp.open("GET", "setdata?state="+led_sts, true); | |
| xhttp.send(); | |
| } | |
| //setInterval(function() | |
| //{ | |
| //getData(); | |
| //}, 2000); | |
| function getData() { | |
| var xhttp = new XMLHttpRequest(); | |
| xhttp.onreadystatechange = function() { | |
| if (this.readyState == 4 && this.status == 200) { | |
| document.getElementById("adc_val").value = | |
| this.responseText; | |
| console.log(this.responseText) | |
| readData(this.responseText); | |
| } | |
| }; | |
| xhttp.open("GET", "getdata", true); | |
| xhttp.send(); | |
| } | |
| getGeneral(""); | |
| function getGeneral(type) { | |
| var xhttp = new XMLHttpRequest(); | |
| xhttp.onreadystatechange = function() { | |
| if (this.readyState == 4 && this.status == 200) { | |
| delay(function(){ | |
| getData() | |
| }, 1500); // end delay | |
| } | |
| }; | |
| xhttp.open("GET", "getgeneral?type="+type, true); | |
| xhttp.send(); | |
| } | |
| function readData(data){ | |
| var lines = data.split('\n'); | |
| var line = ""; | |
| for(var i = 0;i < lines.length;i++){ | |
| line = lines[i].trim(); | |
| console.log(line); | |
| getTypeLine(line); | |
| } | |
| } | |
| function getTypeLine(line){ | |
| var temp =""; | |
| temp = hasPrefix(line, "QM+"); | |
| if(temp != ""){ | |
| return viewMode(temp); | |
| } | |
| temp = hasPrefix(line, "QA+"); | |
| if(temp != ""){ | |
| return viewVolumn(temp); | |
| } | |
| temp = hasPrefix(line, "MP+"); | |
| if(temp != ""){ | |
| return viewStatus(temp); | |
| } | |
| temp = hasPrefix(line, "M1+"); | |
| if(temp != ""){ | |
| return viewStatus("01");//default is play | |
| } | |
| } | |
| function viewMode(text){ | |
| console.log('check mode') | |
| console.log(text) | |
| var selectElement = document.getElementById("typeaudio"); | |
| for (var i = 0; i < selectElement.options.length; i++) { | |
| var option = selectElement.options[i]; | |
| // Check if the current option has the desired attribute value | |
| if (option.getAttribute("data-view") === text) { | |
| // Set the selected attribute of the matching option to true | |
| option.selected = true; | |
| // Optionally, break the loop if you only want to select the first matching option | |
| break; | |
| } | |
| } | |
| } | |
| function viewVolumn(text){ | |
| console.log('check volumn') | |
| document.getElementById("viewvolumn").innerHTML = text; | |
| } | |
| function viewStatus(text){ | |
| console.log('check status tool') | |
| var statusat = ""; | |
| switch(text) { | |
| case "00": | |
| statusat = "Stop"; | |
| // code block | |
| break; | |
| case "01": | |
| // code block | |
| statusat = "Play"; | |
| break; | |
| case "02": | |
| statusat = "Pause"; | |
| // code block | |
| break; | |
| default: | |
| // code block | |
| } | |
| document.getElementById("viewstatus").innerHTML = statusat; | |
| } | |
| function hasPrefix(str, prefix) { | |
| //return str.startsWith(prefix); | |
| if (str.startsWith(prefix)) { | |
| return str.substring(prefix.length); | |
| } else { | |
| return ""; | |
| } | |
| } | |
| </script> | |
| </center> | |
| </body> | |
| </html> | |
| )====="; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html><body> | |
| <?php | |
| $servername = "localhost"; | |
| // REPLACE with your Database name | |
| $dbname = "u204144224_iot"; | |
| // REPLACE with Database user | |
| $username = "u204144224_iot"; | |
| // REPLACE with Database user password | |
| $password = "222#:gr$1"; | |
| // Create connection | |
| $conn = new mysqli($servername, $username, $password, $dbname); | |
| // Check connection | |
| if ($conn->connect_error) { | |
| die("Connection failed: " . $conn->connect_error); | |
| } | |
| $sql = "SELECT id, sensor, location, value1, value2, value3, reading_time,wifi,ip FROM track_on ORDER BY id DESC limit 100"; | |
| echo '<table cellspacing="5" cellpadding="5"> | |
| <tr> | |
| <td>ID</td> | |
| <td>Sensor</td> | |
| <td>Location</td> | |
| <td>Value 1</td> | |
| <td>Value 2</td> | |
| <td>Value 3</td> | |
| <td>Wifi</td> | |
| <td>Ip</td> | |
| <td>Timestamp</td> | |
| </tr>'; | |
| if ($result = $conn->query($sql)) { | |
| while ($row = $result->fetch_assoc()) { | |
| $row_id = $row["id"]; | |
| $row_sensor = $row["sensor"]; | |
| $row_location = $row["location"]; | |
| $row_value1 = $row["value1"]; | |
| $row_value2 = $row["value2"]; | |
| $row_value3 = $row["value3"]; | |
| $wifi = $row["wifi"]; | |
| $ip = $row["ip"]; | |
| $row_reading_time = $row["reading_time"]; | |
| // Uncomment to set timezone to - 1 hour (you can change 1 to any number) | |
| //$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time - 1 hours")); | |
| // Uncomment to set timezone to + 4 hours (you can change 4 to any number) | |
| //$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time + 4 hours")); | |
| echo '<tr> | |
| <td>' . $row_id . '</td> | |
| <td>' . $row_sensor . '</td> | |
| <td>' . $row_location . '</td> | |
| <td>' . $row_value1 . '</td> | |
| <td>' . $row_value2 . '</td> | |
| <td>' . $row_value3 . '</td> | |
| <td>' . $wifi . '</td> | |
| <td>' . $ip . '</td> | |
| <td>' . date("Y-m-d H:i:s", strtotime("$row_reading_time + 7 hours")) . '</td> | |
| </tr>'; | |
| } | |
| $result->free(); | |
| } | |
| $conn->close(); | |
| ?> | |
| </table> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| $servername = "localhost"; | |
| // REPLACE with your Database name | |
| $dbname = "u204144224_iot"; | |
| // REPLACE with Database user | |
| $username = "u204144224_iot"; | |
| // REPLACE with Database user password | |
| $password = "222#:gr$1"; | |
| // Keep this API Key value to be compatible with the ESP32 code provided in the project page. | |
| // If you change this value, the ESP32 sketch needs to match | |
| $api_key_value = "tPmAT5Ab3j7F9"; | |
| $api_key= $sensor = $location = $value1 = $value2 = $value3 = ""; | |
| if ($_SERVER["REQUEST_METHOD"] == "POST") { | |
| $api_key = test_input($_POST["api_key"]); | |
| if($api_key == $api_key_value) { | |
| $sensor = test_input($_POST["sensor"]); | |
| $location = test_input($_POST["location"]); | |
| $value1 = test_input($_POST["value1"]); | |
| $value2 = test_input($_POST["value2"]); | |
| $value3 = test_input($_POST["value3"]); | |
| $wifi = test_input($_POST["wifi"]); | |
| $ip = test_input($_POST["ip"]); | |
| // Create connection | |
| $conn = new mysqli($servername, $username, $password, $dbname); | |
| // Check connection | |
| if ($conn->connect_error) { | |
| die("Connection failed: " . $conn->connect_error); | |
| } | |
| $sql = "INSERT INTO track_on (sensor, location, value1, value2, value3, wifi, ip) | |
| VALUES ('" . $sensor . "', '" . $location . "', '" . $value1 . "', '" . $value2 . "', '" . $value3 ."', '" . $wifi ."', '" . $ip . "')"; | |
| if ($conn->query($sql) === TRUE) { | |
| echo "New record created successfully"; | |
| } | |
| else { | |
| echo "Error: " . $sql . "<br>" . $conn->error; | |
| } | |
| $conn->close(); | |
| } | |
| else { | |
| echo "Wrong API Key provided."; | |
| } | |
| } | |
| else { | |
| echo "No data posted with HTTP POST."; | |
| } | |
| function test_input($data) { | |
| $data = trim($data); | |
| $data = stripslashes($data); | |
| $data = htmlspecialchars($data); | |
| return $data; | |
| } |
Author
tranchausky
commented
Jan 28, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
