Skip to content

Instantly share code, notes, and snippets.

@tranchausky
Last active January 28, 2024 11:12
Show Gist options
  • Save tranchausky/72282bf1a181242a5c411f50b4ba0e1e to your computer and use it in GitHub Desktop.
Save tranchausky/72282bf1a181242a5c411f50b4ba0e1e to your computer and use it in GitHub Desktop.
bt201 + nanoMcu + website
#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;
}
}
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>
)=====";
<!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>
<?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;
}
@tranchausky
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment