add RTC
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# Script to read data from BME280
|
# Script to read data from BME280
|
||||||
# Sensor connected to i2c on address 77 (use sudo i2cdetect -y 1 to get the address )
|
# Sensor connected to i2c on address 76 (use sudo i2cdetect -y 1 to get the address )
|
||||||
# sudo python3 /var/www/nebuleair_pro_4g/BME280/read.py
|
# sudo python3 /var/www/nebuleair_pro_4g/BME280/read.py
|
||||||
|
|
||||||
import board
|
import board
|
||||||
|
|||||||
20
README.md
20
README.md
@@ -66,7 +66,7 @@ sudo chmod 777 /dev/ttyAMA*
|
|||||||
|
|
||||||
## I2C
|
## I2C
|
||||||
|
|
||||||
Decibel meter and BME280 is connected via I2C.
|
Decibel meter, BME280 and the RTC module (DS3231) is connected via I2C.
|
||||||
|
|
||||||
Need to activate by modifying `sudo nano /boot/firmware/config.txt`
|
Need to activate by modifying `sudo nano /boot/firmware/config.txt`
|
||||||
|
|
||||||
@@ -82,14 +82,23 @@ sudo chmod 777 /dev/i2c-1
|
|||||||
|
|
||||||
Attention: sometimes activation with config.txt do not work, you need to activate i2c with `sudo raspi-config` and go to "Interface" -> I2C -> enable.
|
Attention: sometimes activation with config.txt do not work, you need to activate i2c with `sudo raspi-config` and go to "Interface" -> I2C -> enable.
|
||||||
|
|
||||||
|
I2C addresses: use `sudo i2cdetect -y 1` to check the connected devices.
|
||||||
|
|
||||||
### BME280
|
### BME280
|
||||||
|
|
||||||
The python script is triggered by the main loop every minutes to get instant temp, hum and press values (no need to have a minute average).
|
The python script is triggered by the main loop every minutes to get instant temp, hum and press values (no need to have a minute average).
|
||||||
|
BME280 address is 0x76.
|
||||||
|
|
||||||
|
### RTC module (DS3231)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Noise sensor
|
### Noise sensor
|
||||||
|
|
||||||
As noise varies a lot, we keep the C program running every seconds to create a moving average for the last 60 seconds (we also gather max and min values).
|
As noise varies a lot, we keep the C program running every seconds to create a moving average for the last 60 seconds (we also gather max and min values).
|
||||||
To keep the script running at boot and stay on we create a systemd service
|
To keep the script running at boot and stay on we create a systemd service.
|
||||||
|
|
||||||
|
Nois sensor address is 0x48.
|
||||||
|
|
||||||
Create the service with `sudo nano /etc/systemd/system/sound_meter.service` and add:
|
Create the service with `sudo nano /etc/systemd/system/sound_meter.service` and add:
|
||||||
```
|
```
|
||||||
@@ -151,11 +160,10 @@ And set the base URL for Sara R4 communication:
|
|||||||
|
|
||||||
### With only 1 NPM
|
### With only 1 NPM
|
||||||
|
|
||||||
Loop every minutes to get the PM values and send it to the server:
|
Loop every minutes to get the PM values and send it to the server (we use flock to be sure the previous script is over before start the new one):
|
||||||
|
|
||||||
```
|
```
|
||||||
* * * * * /usr/bin/python3 /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.py >> /var/www/nebuleair_pro_4g/logs/loop.log 2>&1
|
* * * * * flock -n /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.lock /usr/bin/python3 /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.py >> /var/www/nebuleair_pro_4g/logs/loop.log 2>&1
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
All in one:
|
All in one:
|
||||||
@@ -164,7 +172,7 @@ All in one:
|
|||||||
@reboot chmod 777 /dev/ttyAMA*
|
@reboot chmod 777 /dev/ttyAMA*
|
||||||
@reboot /var/www/nebuleair_pro_4g/boot_hotspot.sh >> /var/www/nebuleair_pro_4g/logs/app.log 2>&1
|
@reboot /var/www/nebuleair_pro_4g/boot_hotspot.sh >> /var/www/nebuleair_pro_4g/logs/app.log 2>&1
|
||||||
@reboot sleep 30 && /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setURL.py ttyAMA2 data.nebuleair.fr >> /var/www/nebuleair_pro_4g/logs/app.log 2>&1
|
@reboot sleep 30 && /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setURL.py ttyAMA2 data.nebuleair.fr >> /var/www/nebuleair_pro_4g/logs/app.log 2>&1
|
||||||
* * * * * /usr/bin/python3 /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.py >> /var/www/nebuleair_pro_4g/logs/loop.log 2>&1
|
* * * * * flock -n /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.lock /usr/bin/python3 /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.py >> /var/www/nebuleair_pro_4g/logs/loop.log 2>&1
|
||||||
0 0 */2 * * > /var/www/nebuleair_pro_4g/logs/loop.log
|
0 0 */2 * * > /var/www/nebuleair_pro_4g/logs/loop.log
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
58
RTC/read.py
Normal file
58
RTC/read.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
'''
|
||||||
|
Script to read time from RTC module
|
||||||
|
I2C connection
|
||||||
|
Address 0x68
|
||||||
|
/usr/bin/python3 /var/www/nebuleair_pro_4g/RTC/read.py
|
||||||
|
'''
|
||||||
|
import smbus2
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
# DS3231 I2C address
|
||||||
|
DS3231_ADDR = 0x68
|
||||||
|
|
||||||
|
# Registers for DS3231
|
||||||
|
REG_TIME = 0x00
|
||||||
|
|
||||||
|
def bcd_to_dec(bcd):
|
||||||
|
return (bcd // 16 * 10) + (bcd % 16)
|
||||||
|
|
||||||
|
def read_time(bus):
|
||||||
|
data = bus.read_i2c_block_data(DS3231_ADDR, REG_TIME, 7)
|
||||||
|
seconds = bcd_to_dec(data[0] & 0x7F)
|
||||||
|
minutes = bcd_to_dec(data[1])
|
||||||
|
hours = bcd_to_dec(data[2] & 0x3F)
|
||||||
|
day = bcd_to_dec(data[4])
|
||||||
|
month = bcd_to_dec(data[5])
|
||||||
|
year = bcd_to_dec(data[6]) + 2000
|
||||||
|
return (year, month, day, hours, minutes, seconds)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Read RTC time
|
||||||
|
bus = smbus2.SMBus(1)
|
||||||
|
year, month, day, hours, minutes, seconds = read_time(bus)
|
||||||
|
rtc_time = datetime(year, month, day, hours, minutes, seconds)
|
||||||
|
|
||||||
|
# Get current system time
|
||||||
|
system_time = datetime.now() #local
|
||||||
|
utc_time = datetime.utcnow() #UTC
|
||||||
|
|
||||||
|
# Print both times
|
||||||
|
#print(f"RTC module Time: {rtc_time.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
#print(f"Sys local Time: {system_time.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
#print(f"Sys UTC Time: {utc_time.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
|
||||||
|
# Create JSON output
|
||||||
|
time_data = {
|
||||||
|
"rtc_module_time": rtc_time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
|
"system_local_time": system_time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
|
"system_utc_time": utc_time.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
}
|
||||||
|
|
||||||
|
print(json.dumps(time_data, indent=4))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
"NextPM_5channels": false,
|
"NextPM_5channels": false,
|
||||||
"i2C_sound": false,
|
"i2C_sound": false,
|
||||||
"i2c_BME": false,
|
"i2c_BME": false,
|
||||||
|
"i2c_RTC": false,
|
||||||
"sshTunnel_port": 59228,
|
"sshTunnel_port": 59228,
|
||||||
"npm1_status": "connected",
|
"npm1_status": "connected",
|
||||||
"SARA_R4_general_status": "connected",
|
"SARA_R4_general_status": "connected",
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
|
|
||||||
<div class="col-lg-4 col-12">
|
<div class="col-lg-3 col-12">
|
||||||
<h3 class="mt-4">Parameters</h3>
|
<h3 class="mt-4">Parameters</h3>
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
@@ -94,11 +94,41 @@
|
|||||||
<!--<button type="submit" class="btn btn-primary">Submit</button>-->
|
<!--<button type="submit" class="btn btn-primary">Submit</button>-->
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- CLOCK-->
|
||||||
|
<div class="col-lg-3 col-12">
|
||||||
|
|
||||||
|
<h3 class="mt-4">Clock</h3>
|
||||||
|
|
||||||
|
<div class="form-check mb-3">
|
||||||
|
<input class="form-check-input" type="checkbox" value="" id="check_RTC" onchange="update_config('i2c_RTC', this.checked)">
|
||||||
|
<label class="form-check-label" for="check_RTC">
|
||||||
|
RTC module (DS3231)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="sys_local_time" class="form-label">System time (local)</label>
|
||||||
|
<input type="text" class="form-control" id="sys_local_time" disabled>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="sys_UTC_time" class="form-label">System time (UTC)</label>
|
||||||
|
<input type="text" class="form-control" id="sys_UTC_time" disabled>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="RTC_utc_time" class="form-label">RTC time (UTC)</label>
|
||||||
|
<input type="text" class="form-control" id="RTC_utc_time" disabled>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- UPDATE-->
|
||||||
|
|
||||||
<div class="col-lg-4 col-12">
|
<div class="col-lg-4 col-12">
|
||||||
<h3 class="mt-4">Updates</h3>
|
<h3 class="mt-4">Updates</h3>
|
||||||
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary" onclick="updateGitPull()">Update firmware</button>
|
<button type="submit" class="btn btn-primary" onclick="updateGitPull()">Update firmware</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -137,6 +167,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
|
|
||||||
fetch('../config.json') // Replace 'deviceID.txt' with 'config.json'
|
fetch('../config.json') // Replace 'deviceID.txt' with 'config.json'
|
||||||
.then(response => response.json()) // Parse response as JSON
|
.then(response => response.json()) // Parse response as JSON
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@@ -156,6 +187,10 @@ window.onload = function() {
|
|||||||
const checkbox = document.getElementById("check_bme280");
|
const checkbox = document.getElementById("check_bme280");
|
||||||
checkbox.checked = data.i2c_BME;
|
checkbox.checked = data.i2c_BME;
|
||||||
|
|
||||||
|
//get BME check
|
||||||
|
const checkbox_RTC = document.getElementById("check_RTC");
|
||||||
|
checkbox_RTC.checked = data.i2c_RTC;
|
||||||
|
|
||||||
//loop activation
|
//loop activation
|
||||||
const flex_loop = document.getElementById("flex_loop");
|
const flex_loop = document.getElementById("flex_loop");
|
||||||
flex_loop.checked = data.loop_activation;
|
flex_loop.checked = data.loop_activation;
|
||||||
@@ -176,20 +211,37 @@ window.onload = function() {
|
|||||||
const device_ID = document.getElementById("device_ID");
|
const device_ID = document.getElementById("device_ID");
|
||||||
device_ID.value = data.deviceID.toUpperCase();
|
device_ID.value = data.deviceID.toUpperCase();
|
||||||
|
|
||||||
//get local RTC
|
//get system time and RTC module
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'launcher.php?type=RTC_time',
|
url: 'launcher.php?type=sys_RTC_module_time',
|
||||||
dataType: 'text', // Specify that you expect a JSON response
|
dataType: 'json', // Specify that you expect a JSON response
|
||||||
method: 'GET', // Use GET or POST depending on your needs
|
method: 'GET', // Use GET or POST depending on your needs
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
console.log("Local RTC: " + response);
|
console.log(response);
|
||||||
const RTC_Element = document.getElementById("RTC_time");
|
// Update the input fields with the received JSON data
|
||||||
RTC_Element.textContent = response;
|
document.getElementById("sys_local_time").value = response.system_local_time;
|
||||||
},
|
document.getElementById("sys_UTC_time").value = response.system_utc_time;
|
||||||
error: function(xhr, status, error) {
|
document.getElementById("RTC_utc_time").value = response.rtc_module_time;
|
||||||
console.error('AJAX request failed:', status, error);
|
},
|
||||||
}
|
error: function(xhr, status, error) {
|
||||||
});
|
console.error('AJAX request failed:', status, error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//get local RTC
|
||||||
|
$.ajax({
|
||||||
|
url: 'launcher.php?type=RTC_time',
|
||||||
|
dataType: 'text', // Specify that you expect a JSON response
|
||||||
|
method: 'GET', // Use GET or POST depending on your needs
|
||||||
|
success: function(response) {
|
||||||
|
console.log("Local RTC: " + response);
|
||||||
|
const RTC_Element = document.getElementById("RTC_time");
|
||||||
|
RTC_Element.textContent = response;
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.error('AJAX request failed:', status, error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(error => console.error('Error loading config.json:', error));
|
.catch(error => console.error('Error loading config.json:', error));
|
||||||
@@ -202,6 +254,7 @@ function update_config(param, value){
|
|||||||
url: 'launcher.php?type=update_config¶m='+param+'&value='+value,
|
url: 'launcher.php?type=update_config¶m='+param+'&value='+value,
|
||||||
dataType: 'text', // Specify that you expect a JSON response
|
dataType: 'text', // Specify that you expect a JSON response
|
||||||
method: 'GET', // Use GET or POST depending on your needs
|
method: 'GET', // Use GET or POST depending on your needs
|
||||||
|
cache: false, // Prevent AJAX from caching
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
},
|
},
|
||||||
@@ -217,6 +270,8 @@ function updateGitPull(){
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'launcher.php?type=git_pull',
|
url: 'launcher.php?type=git_pull',
|
||||||
method: 'GET', // Use GET or POST depending on your needs
|
method: 'GET', // Use GET or POST depending on your needs
|
||||||
|
dataType: 'text', // Specify that you expect a JSON response
|
||||||
|
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
// Handle success response if needed
|
// Handle success response if needed
|
||||||
console.log(response);
|
console.log(response);
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
// ✅ Prevents caching → Adds headers to ensure fresh response.
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
||||||
|
header("Pragma: no-cache");
|
||||||
|
|
||||||
$type=$_GET['type'];
|
$type=$_GET['type'];
|
||||||
|
|
||||||
if ($type == "update_config") {
|
if ($type == "update_config") {
|
||||||
@@ -25,6 +30,12 @@ if ($type == "RTC_time") {
|
|||||||
echo $time;
|
echo $time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($type == "sys_RTC_module_time") {
|
||||||
|
$command = '/usr/bin/python3 /var/www/nebuleair_pro_4g/RTC/read.py';
|
||||||
|
$output = shell_exec($command);
|
||||||
|
echo $output;
|
||||||
|
}
|
||||||
|
|
||||||
if ($type == "git_pull") {
|
if ($type == "git_pull") {
|
||||||
$command = 'sudo git pull';
|
$command = 'sudo git pull';
|
||||||
$output = shell_exec($command);
|
$output = shell_exec($command);
|
||||||
|
|||||||
Reference in New Issue
Block a user