Home Automation Treadmill Bike
Hello, this is my home automation project, the bicycle treadmill, this bicycle treadmill had a clock and a step counter at the beginning, but as time passed it no longer worked very well, so I decided to use the raspberry pi 3 b+, a rPi screen and a IR sensor obstacle detector, create a simple interface for the end user, in which the end user can change music whenever he wants, also see a cartesian plane where the number of steps taken by the end user is shown. achieved thanks to the IR sensor obstacle detector against time.
Next I will show how I made this project of mine. For this project, a treadmill will be used.
A raspberry pi 3 b+, with a 3.5-inch rPi screen.
Use the IR sensor obstacle detector to capture every step you take on the treadmill.
For the case, I had it printed on a 3d printer, the model is on the following page: https://www.thingiverse.com/thing:3473751/files.
With adhesive velcro attach it to the treadmill.
To attach the IR sensor obstacle detector I did it as follows.
The sensor connection is as follows.
For the programming of the raspberry pi I used html, css, javascript, python, bash and mysql.
For the music section html, css and javascript were used.
music.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Simple Music Player</title>
<!-- Load FontAwesome icons -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css">
<!-- Load the custom CSS style file -->
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="player">
<!-- Define the section for displaying details -->
<div class="details">
<div class="now-playing">REPRODUCIENDO x DE y</div>
<div class="track-name">Nombre de la cancion</div>
<div class="track-art"></div>
<div class="track-artist">------------------------------------------------------------</div>
</div>
<!-- Define the section for displaying track buttons -->
<div class="buttons">
<div class="prev-track" onclick="prevTrack()">
<i class="fa fa-step-backward fa-2x"></i>
</div>
<div class="playpause-track" onclick="playpauseTrack()">
<i class="fa fa-play-circle fa-5x"></i>
</div>
<div class="next-track" onclick="nextTrack()">
<i class="fa fa-step-forward fa-2x"></i>
</div>
</div>
<div class="slider_container">
<div class="current-time">00:00</div>
<input type="range" min="1" max="100"
value="0" class="seek_slider" onchange="seekTo()">
<div class="total-duration">00:00</div>
</div>
<div class="slider_container">
<i class="fa fa-volume-down"></i>
<input type="range" min="1" max="100"
value="99" class="volume_slider" onchange="setVolume()">
<i class="fa fa-volume-up"></i>
</div>
</div>
<!-- Load the main script for the player -->
<script src="main.js"></script>
</body>
</html>
main.js:
// Select all the elements in the HTML page
// and assign them to a variable
let now_playing = document.querySelector(".now-playing");
let track_art = document.querySelector(".track-art");
let track_name = document.querySelector(".track-name");
let track_artist = document.querySelector(".track-artist");
let playpause_btn = document.querySelector(".playpause-track");
let next_btn = document.querySelector(".next-track");
let prev_btn = document.querySelector(".prev-track");
let seek_slider = document.querySelector(".seek_slider");
let volume_slider = document.querySelector(".volume_slider");
let curr_time = document.querySelector(".current-time");
let total_duration = document.querySelector(".total-duration");
// Specify globally used values
let track_index = 0;
let isPlaying = false;
let updateTimer;
// Create the audio element for the player
let curr_track = document.createElement('audio');
// Define the list of tracks that have to be played
let track_list = [
{
name: "AmoresLejanos",
artist: "------------------------------------------------------------",
image: "Image URL",
path: "AmoresLejanos.mp3"
},
{
name: "Time",
artist: "------------------------------------------------------------",
image: "Image URL",
path: "Time.mp3"
},
];
function loadTrack(track_index) {
// Clear the previous seek timer
clearInterval(updateTimer);
resetValues();
// Load a new track
curr_track.src = track_list[track_index].path;
curr_track.load();
// Update details of the track
track_art.style.backgroundImage =
"url(" + track_list[track_index].image + ")";
track_name.textContent = track_list[track_index].name;
track_artist.textContent = track_list[track_index].artist;
now_playing.textContent =
"PLAYING " + (track_index + 1) + " OF " + track_list.length;
// Set an interval of 1000 milliseconds
// for updating the seek slider
updateTimer = setInterval(seekUpdate, 1000);
// Move to the next track if the current finishes playing
// using the 'ended' event
curr_track.addEventListener("ended", nextTrack);
// Apply a random background color
random_bg_color();
}
function random_bg_color() {
// Get a random number between 64 to 256
// (for getting lighter colors)
let red = Math.floor(Math.random() * 256) + 64;
let green = Math.floor(Math.random() * 256) + 64;
let blue = Math.floor(Math.random() * 256) + 64;
// Construct a color withe the given values
let bgColor = "rgb(" + red + ", " + green + ", " + blue + ")";
// Set the background to the new color
document.body.style.background = bgColor;
}
// Function to reset all values to their default
function resetValues() {
curr_time.textContent = "00:00";
total_duration.textContent = "00:00";
seek_slider.value = 0;
}
function playpauseTrack() {
// Switch between playing and pausing
// depending on the current state
if (!isPlaying) playTrack();
else pauseTrack();
}
function playTrack() {
// Play the loaded track
curr_track.play();
isPlaying = true;
// Replace icon with the pause icon
playpause_btn.innerHTML = '<i class="fa fa-pause-circle fa-5x"></i>';
}
function pauseTrack() {
// Pause the loaded track
curr_track.pause();
isPlaying = false;
// Replace icon with the play icon
playpause_btn.innerHTML = '<i class="fa fa-play-circle fa-5x"></i>';
}
function nextTrack() {
// Go back to the first track if the
// current one is the last in the track list
if (track_index < track_list.length - 1)
track_index += 1;
else track_index = 0;
// Load and play the new track
loadTrack(track_index);
playTrack();
}
function prevTrack() {
// Go back to the last track if the
// current one is the first in the track list
if (track_index > 0)
track_index -= 1;
else track_index = track_list.length - 1;
// Load and play the new track
loadTrack(track_index);
playTrack();
}
function seekTo() {
// Calculate the seek position by the
// percentage of the seek slider
// and get the relative duration to the track
seekto = curr_track.duration * (seek_slider.value / 100);
// Set the current track position to the calculated seek position
curr_track.currentTime = seekto;
}
function setVolume() {
// Set the volume according to the
// percentage of the volume slider set
curr_track.volume = volume_slider.value / 100;
}
function seekUpdate() {
let seekPosition = 0;
// Check if the current track duration is a legible number
if (!isNaN(curr_track.duration)) {
seekPosition = curr_track.currentTime * (100 / curr_track.duration);
seek_slider.value = seekPosition;
// Calculate the time left and the total duration
let currentMinutes = Math.floor(curr_track.currentTime / 60);
let currentSeconds = Math.floor(curr_track.currentTime - currentMinutes * 60);
let durationMinutes = Math.floor(curr_track.duration / 60);
let durationSeconds = Math.floor(curr_track.duration - durationMinutes * 60);
// Add a zero to the single digit time values
if (currentSeconds < 10) { currentSeconds = "0" + currentSeconds; }
if (durationSeconds < 10) { durationSeconds = "0" + durationSeconds; }
if (currentMinutes < 10) { currentMinutes = "0" + currentMinutes; }
if (durationMinutes < 10) { durationMinutes = "0" + durationMinutes; }
// Display the updated duration
curr_time.textContent = currentMinutes + ":" + currentSeconds;
total_duration.textContent = durationMinutes + ":" + durationSeconds;
}
}
style.css:
body {
background-color: lightgreen;
/* Smoothly transition the background color */
transition: background-color .5s;
}
/* Using flex with the column direction to
align items in a vertical direction */
.player {
height: 95vh;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
}
.details {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
margin-top: 25px;
}
.track-art {
margin: 1px;
height: 1px;
width: 10px;
/*background-image: URL(
"https://source.unsplash.com/Qrspubmx6kE/640x360");*/
background-size: cover;
background-position: center;
border-radius: 15%;
}
/* Changing the font sizes to suitable ones */
.now-playing {
font-size: 1rem;
}
.track-name {
font-size: 3rem;
}
.track-artist {
font-size: 1.5rem;
}
/* Using flex with the row direction to
align items in a horizontal direction */
.buttons {
display: flex;
flex-direction: row;
align-items: center;
}
.playpause-track,
.prev-track,
.next-track {
padding: 25px;
opacity: 0.8;
/* Smoothly transition the opacity */
transition: opacity .2s;
}
/* Change the opacity when mouse is hovered */
.playpause-track:hover,
.prev-track:hover,
.next-track:hover {
opacity: 1.0;
}
/* Define the slider width so that it scales properly */
.slider_container {
width: 75%;
max-width: 400px;
display: flex;
justify-content: center;
align-items: center;
}
/* Modify the appearance of the slider */
.seek_slider, .volume_slider {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
height: 5px;
background: black;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
/* Modify the appearance of the slider thumb */
.seek_slider::-webkit-slider-thumb,
.volume_slider::-webkit-slider-thumb {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 15px;
height: 15px;
background: white;
cursor: pointer;
border-radius: 50%;
}
/* Change the opacity when mouse is hovered */
.seek_slider:hover,
.volume_slider:hover {
opacity: 1.0;
}
.seek_slider {
width: 60%;
}
.volume_slider {
width: 30%;
}
.current-time,
.total-duration {
padding: 10px;
}
i.fa-volume-down,
i.fa-volume-up {
padding: 10px;
}
/* Change the mouse cursor to a pointer
when hovered over */
i.fa-play-circle,
i.fa-pause-circle,
i.fa-step-forward,
i.fa-step-backward {
cursor: pointer;
}
Before showing the section of the Cartesian plane, a very simple database was created to create it, which is shown below.
For the creation of the Cartesian plane section, the javascript highcharts library was used.
sensor.php:
<?php
$mysqli = new mysqli("localhost","user_sensor","user_pass_301","sensor");
// Check connection
if ($mysqli -> connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli -> connect_error;
exit();
}
$index = 0;
$dateSensor = array();
// Perform query
if ($result = $mysqli -> query("SELECT datetime, cantidad_pasos FROM tsensor")) {
//echo "Returned rows are: " . $result -> num_rows;
// Free result set
//$result -> free_result();
while($row = $result -> fetch_row())
{
//printf("%s %s %s <br>", $row[0], $row[1], $row[2]);
$dateSensor[$index]=$row;
$index = $index + 1;
}
$result -> free_result();
}
//echo json_encode($dateSensor, JSON_NUMERIC_CHECK);
$mysqli -> close();
?>
<?php
$page = $_SERVER['PHP_SELF'];
$sec = "10";
?>
<!DOCTYPE html>
<html>
<head>
<title>Datos</title>
<meta http-equiv="refresh" content="<?php echo $sec?>;URL='<?php echo $page?>'">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(function () {
$('#container').highcharts({
chart: {
type: 'line'
},
time: {
timezone: 'Bolivia/La Paz'
},
title: {
text: 'Cantidad de pasos vs Tiempo'
},
xAxis: {
title: {
text: 'Tiempo'
},
type: 'datetime',
},
yAxis: {
title: {
text: 'Cantidad Pasos'
}
},
series: [{
name: 'Pasos',
data: <?php echo json_encode($dateSensor, JSON_NUMERIC_CHECK);?>
}]
});
});
</script>
<script src="charts/js/highcharts.js"></script>
<script src="charts/js/modules/exporting.js"></script>
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-body">
<div id="container"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Now with these two sections, the main page that will be shown below is created.
index.php:
<!DOCTYPE html>
<html>
<head>
<title>Trotadora</title>
<style type="text/css">
@import url('https://fonts.googleapis.com/css?family=Lato:100,100i,300,300i,400,400i,700,700i,900,900i');
*
{
margin: 0;
padding: 0;
}
body
{
font-family: 'Lato', sans-serif;
font-size: 14px;
color: #999999;
word-wrap:break-word;
}
p
{
margin: 0 0 10px;
}
ul
{
list-style: none;
}
button {
border-radius: 50%;
padding: 0.5em;
width: 60px;
height: 60px;
border: 2px solid #A5ADB0;
color: #A5ADB0 ;
position: relative;
}
#button_home_2 {
border-radius: 50%;
padding: 0.5em;
width: 20px;
height: 20px;
border: 2px solid #A5ADB0;
color: #A5ADB0 ;
position: relative;
}
button:hover {
border: 2px solid #A5ADB0;
background-color: #8F9496;
color: #ffffff;
}
.container {
height: 200px;
position: relative;
}
.center {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
}
/*
button::before {
content: " ";
position: absolute;
display: block;
background-color: #727778 ;
width: 2px;
left: 12px;
top: 5px;
bottom: 3px;
transform: rotate(45deg);
}
button::after {
content: " ";
position: absolute;
display: block;
background-color: #727778 ;
height: 2px;
top:12px;
left: 5px;
right: 5px;
transform: rotate(45deg);
}
*/
.container {
width: 100%;
margin: auto;
font-weight: 900;
text-transform: uppercase;
text-align: center;
padding: 0 0 30px;
}
/*.take-input {
margin: 50px 0 0;
}
.take-input input {
width: 400px;
height: 35px;
padding: 0 10px;
border-radius: 5px;
border: 1px solid #ececec;
margin: 0 15px 0 0;
font-size: 15px;
}*/
a, a:link, a:visited {
text-decoration: none;
padding: 9px 15px;
border: 1px solid #A5ADB0;
border-radius: 5px;
color: gray;
}
.animate {
font-size: 100px;
margin: 100px 0 0;
border-bottom: 2px solid #A5ADB0;
font-weight: 90;
}
.animate span {
display: inline-block;
}
a.repeat {
display: inline-block;
font-size: 12px;
text-transform: none;
text-decoration: none;
color: orange;
padding: 5px 12px;
border: 1px solid rgba(0, 0, 0, 0.15);
font-weight: normal;
margin: 0 0 0 50px;
border-radius: 3px;
position: relative;
bottom: 15px;
}
a.repeat:hover {
background: rgba(0, 0, 0, 0.7);
color: white;
}
.animate span:nth-of-type(2) {
animation-delay: .05s;
}
.animate span:nth-of-type(3) {
animation-delay: .1s;
}
.animate span:nth-of-type(4) {
animation-delay: .15s;
}
.animate span:nth-of-type(5) {
animation-delay: .2s;
}
.animate span:nth-of-type(6) {
animation-delay: .25s;
}
.animate span:nth-of-type(7) {
animation-delay: .3s;
}
.animate span:nth-of-type(8) {
animation-delay: .35s;
}
.animate span:nth-of-type(9) {
animation-delay: .4s;
}
.animate span:nth-of-type(10) {
animation-delay: .45s;
}
.animate span:nth-of-type(11) {
animation-delay: .5s;
}
.animate span:nth-of-type(12) {
animation-delay: .55s;
}
.animate span:nth-of-type(13) {
animation-delay: .6s;
}
.animate span:nth-of-type(14) {
animation-delay: .65s;
}
.animate span:nth-of-type(15) {
animation-delay: .7s;
}
.animate span:nth-of-type(16) {
animation-delay: .75s;
}
.animate span:nth-of-type(17) {
animation-delay: .8s;
}
.animate span:nth-of-type(18) {
animation-delay: .85s;
}
.animate span:nth-of-type(19) {
animation-delay: .9s;
}
.animate span:nth-of-type(20) {
animation-delay: .95s;
}
/* Animation Seven */
.seven span {
color: #A5ADB0;
opacity: 0;
transform: translate(-150px, 0) scale(.3);
animation: leftRight .5s forwards;
}
@keyframes leftRight {
40% {
transform: translate(50px, 0) scale(.7);
opacity: 1;
color: #A5ADB0;
}
60% {
color: #A5ADB0;
}
80% {
transform: translate(0) scale(2);
opacity: 0;
}
100% {
transform: translate(0) scale(1);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="container">
<div class="animate seven">
<span>T</span><span>R</span><span>O</span><span>T</span><span>A</span><span>D</span><span>O</span><span>R</span><span>A</span>
</div>
</div>
<div class="container">
<div class="center">
<button type="button" id="button_music">☼</button>
<button type="button" id="button_steps">☼</button>
</div>
</div>
<iframe id="music_section"
title="Seccion de musica"
width="500"
height="400"
src="http://localhost/music.html">
</iframe><button type="button" id="button_home_1">☼</button>
<br><br><br><br>
<iframe id="steps_section"
title="Seccion de la tabla de pasos"
width="700"
height="455"
src="http://localhost/sensor.php">
</iframe><button type="button" id="button_home_2">☼</button>
<script type="text/javascript">
document.getElementById("button_music").onclick = function()
{
location.href = '#music_section';
};
document.getElementById("button_steps").onclick = function()
{
location.href = '#steps_section';
};
document.getElementById("button_home_1").onclick = function()
{
location.href = '#';
};
document.getElementById("button_home_2").onclick = function()
{
location.href = '#';
};
$(function(){
$('.repeat').click(function(){
var classes = $(this).parent().attr('class');
$(this).parent().attr('class', 'animate');
var indicator = $(this);
setTimeout(function(){
$(indicator).parent().addClass(classes);
}, 20);
});
});
</script>
</body>
</html>
Where the songs should be added are in the /var/www/html/ directory after you have to update the main.js, but I automate the adding process with the following script.
add_music.sh:
var1="// Select all the elements in the HTML page
// and assign them to a variable
let now_playing = document.querySelector(\".now-playing\");
let track_art = document.querySelector(\".track-art\");
let track_name = document.querySelector(\".track-name\");
let track_artist = document.querySelector(\".track-artist\");
let playpause_btn = document.querySelector(\".playpause-track\");
let next_btn = document.querySelector(\".next-track\");
let prev_btn = document.querySelector(\".prev-track\");
let seek_slider = document.querySelector(\".seek_slider\");
let volume_slider = document.querySelector(\".volume_slider\");
let curr_time = document.querySelector(\".current-time\");
let total_duration = document.querySelector(\".total-duration\");
// Specify globally used values
let track_index = 0;
let isPlaying = false;
let updateTimer;
// Create the audio element for the player
let curr_track = document.createElement('audio');
// Define the list of tracks that have to be played
let track_list = ["
var2="
];
function loadTrack(track_index) {
// Clear the previous seek timer
clearInterval(updateTimer);
resetValues();
// Load a new track
curr_track.src = track_list[track_index].path;
curr_track.load();
// Update details of the track
track_art.style.backgroundImage =
\"url(\" + track_list[track_index].image + \")\";
track_name.textContent = track_list[track_index].name;
track_artist.textContent = track_list[track_index].artist;
now_playing.textContent =
\"PLAYING \" + (track_index + 1) + \" OF \" + track_list.length;
// Set an interval of 1000 milliseconds
// for updating the seek slider
updateTimer = setInterval(seekUpdate, 1000);
// Move to the next track if the current finishes playing
// using the 'ended' event
curr_track.addEventListener(\"ended\", nextTrack);
// Apply a random background color
random_bg_color();
}
function random_bg_color() {
// Get a random number between 64 to 256
// (for getting lighter colors)
let red = Math.floor(Math.random() * 256) + 64;
let green = Math.floor(Math.random() * 256) + 64;
let blue = Math.floor(Math.random() * 256) + 64;
// Construct a color withe the given values
let bgColor = \"rgb(\" + red + \", \" + green + \", \" + blue + \")\";
// Set the background to the new color
document.body.style.background = bgColor;
}
// Function to reset all values to their default
function resetValues() {
curr_time.textContent = \"00:00\";
total_duration.textContent = \"00:00\";
seek_slider.value = 0;
}
function playpauseTrack() {
// Switch between playing and pausing
// depending on the current state
if (!isPlaying) playTrack();
else pauseTrack();
}
function playTrack() {
// Play the loaded track
curr_track.play();
isPlaying = true;
// Replace icon with the pause icon
playpause_btn.innerHTML = '<i class=\"fa fa-pause-circle fa-5x\"></i>';
}
function pauseTrack() {
// Pause the loaded track
curr_track.pause();
isPlaying = false;
// Replace icon with the play icon
playpause_btn.innerHTML = '<i class=\"fa fa-play-circle fa-5x\"></i>';
}
function nextTrack() {
// Go back to the first track if the
// current one is the last in the track list
if (track_index < track_list.length - 1)
track_index += 1;
else track_index = 0;
// Load and play the new track
loadTrack(track_index);
playTrack();
}
function prevTrack() {
// Go back to the last track if the
// current one is the first in the track list
if (track_index > 0)
track_index -= 1;
else track_index = track_list.length - 1;
// Load and play the new track
loadTrack(track_index);
playTrack();
}
function seekTo() {
// Calculate the seek position by the
// percentage of the seek slider
// and get the relative duration to the track
seekto = curr_track.duration * (seek_slider.value / 100);
// Set the current track position to the calculated seek position
curr_track.currentTime = seekto;
}
function setVolume() {
// Set the volume according to the
// percentage of the volume slider set
curr_track.volume = volume_slider.value / 100;
}
function seekUpdate() {
let seekPosition = 0;
// Check if the current track duration is a legible number
if (!isNaN(curr_track.duration)) {
seekPosition = curr_track.currentTime * (100 / curr_track.duration);
seek_slider.value = seekPosition;
// Calculate the time left and the total duration
let currentMinutes = Math.floor(curr_track.currentTime / 60);
let currentSeconds = Math.floor(curr_track.currentTime - currentMinutes * 60);
let durationMinutes = Math.floor(curr_track.duration / 60);
let durationSeconds = Math.floor(curr_track.duration - durationMinutes * 60);
// Add a zero to the single digit time values
if (currentSeconds < 10) { currentSeconds = \"0\" + currentSeconds; }
if (durationSeconds < 10) { durationSeconds = \"0\" + durationSeconds; }
if (currentMinutes < 10) { currentMinutes = \"0\" + currentMinutes; }
if (durationMinutes < 10) { durationMinutes = \"0\" + durationMinutes; }
// Display the updated duration
curr_time.textContent = currentMinutes + \":\" + currentSeconds;
total_duration.textContent = durationMinutes + \":\" + durationSeconds;
}
}"
set=""
for i in $(ls);
do
extension=$(sudo echo $i | tr '.' ' ' | awk '{print $2}')
name=$(sudo echo $i | tr '.' ' ' | awk '{print $1}')
element="
{
name: \"$name\",
artist: \"------------------------------------------------------------\",
image: \"Image URL\",
path: \"$i\"
},
"
if [ $extension = "mp3" ]
then
set+="$element"
fi
done
var="$var1$set$var2"
sudo echo "$var" > main.js
To read the sensor and send it to the database, python was used:
sensor.py
#!/usr/bin/env python
import os
import time
import datetime
import glob
import MySQLdb
from time import strftime
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
# Declaration of the input pin which is connected with the sensor
GPIO_PIN = 12
GPIO.setup(GPIO_PIN, GPIO.IN, pull_up_down = GPIO.PUD_UP)
def dateTime(): #get UNIX time
secs = float(time.time())
secs = secs*1000
return secs
def sensorRead(x):
try:
if not GPIO.input(GPIO_PIN):
return x + 1
except KeyboardInterrupt:
GPIO.cleanup()
return x
db = MySQLdb.connect(host = "localhost", user = "user_sensor", passwd = "user_pass_301", db = "sensor")
cur = db.cursor()
delayTime = 0.2
while(True):
secs = dateTime()
#read = sensorRead(1)
query = "select * from tsensor ORDER BY id DESC LIMIT 1"
cur.execute(query)
myresult = cur.fetchall()
#print(myresult[0][2])
read = sensorRead(myresult[0][2])
sql = ("""INSERT INTO tsensor (datetime, cantidad_pasos) VALUES (%s,%s)""", (secs, read))
try:
#print("Writing to the database...")
cur.execute(*sql)
db.commit()
#print("Write complete")
except:
db.rollback()
#print("We have a problem")
time.sleep(delayTime)
cur.close()
db.close()
Note that this script must be executed every time the main page is initialized in the browser of the raspberry pi 3, when it is in full screen mode.
I have a bash script that every time the raspberry pi 3 is turned on this script is executed, the purpose of this regarding the project is that every time the raspberry pi 3 is turned on it starts in 0 steps and this be recorded in the database.
sudo mysql -uroot -proot sensor -e "DELETE FROM tsensor WHERE datetime >= 0"
sudo mysql -uroot -proot sensor -e "INSERT INTO tsensor(datetime, cantidad_pasos) VALUES($(($(date +%s%N)/1000000)), 0)"
The following article can be of help for the proper functionality of the above script shown: https://www.dexterindustries.com/howto/run-a-program-on-your-raspberry-pi-at-startup/.
Finally I will show the total operation of all these scripts.
All these scripts are in my github: https://github.com/diegojoel301/Bicicleta-Trotadora-Domotizada.
That would be my project which I will work on in a week considering that I have a somewhat busy life, thank you very much for viewing my article.