Code backup
This commit is contained in:
2026-05-10 16:59:01 +02:00
commit 368d6fafea
796 changed files with 315310 additions and 0 deletions
@@ -0,0 +1,82 @@
import serial
import struct
import csv
from datetime import datetime, timedelta
# ================= CONFIG =================
PORT = "COM3" # <-- cambia
BAUD = 921600
OUT_CSV = "imu_log.csv"
FRAME_FMT = "<H I 6h 6h H" # little-endian
FRAME_SIZE = struct.calcsize(FRAME_FMT)
MAGIC = 0xABCD
# ================= CRC ====================
def crc16_xor(data: bytes) -> int:
c = 0
for b in data:
c ^= b
return c & 0xFFFF
# ================= SERIAL =================
ser = serial.Serial(PORT, BAUD, timeout=1)
buffer = bytearray()
start_wall_time = None
start_ts_us = None
print("Listening...")
try:
with open(OUT_CSV, "w", newline="") as f:
writer = csv.writer(f)
writer.writerow([
"timestamp",
"imu1_ax","imu1_ay","imu1_az","imu1_gx","imu1_gy","imu1_gz",
"imu2_ax","imu2_ay","imu2_az","imu2_gx","imu2_gy","imu2_gz"
])
while True:
buffer += ser.read(1024)
while len(buffer) >= FRAME_SIZE:
# cerca MAGIC
if buffer[0] != 0xCD or buffer[1] != 0xAB:
buffer.pop(0)
continue
frame = buffer[:FRAME_SIZE]
buffer = buffer[FRAME_SIZE:]
# unpack
magic, ts_us, *imu, crc = struct.unpack(FRAME_FMT, frame)
# CRC check
if crc16_xor(frame[:-2]) != crc:
continue
# inizializza tempo base
if start_wall_time is None:
start_wall_time = datetime.now()
start_ts_us = ts_us
# timestamp assoluto coerente con ESP
delta_us = ts_us - start_ts_us
ts = start_wall_time + timedelta(microseconds=delta_us)
writer.writerow([
ts.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3],
*imu
])
# logging si può escludere
print(
ts.strftime("%H:%M:%S.%f")[:-3],
"| 1:", tuple(imu[:6]),
"| 2:", tuple(imu[6:])
)
except KeyboardInterrupt:
ser.close()
print("Stopped")
@@ -0,0 +1,69 @@
import serial
import struct
from datetime import datetime, timedelta
# ================= CONFIG =================
PORT = "COM17" # <-- cambia
BAUD = 2000000
OUT_FILE = "imu_log.txt"
FRAME_FMT = "<H I 6f 6f H"
# FRAME_FMT = "<H I 6h 6h H"
FRAME_SIZE = struct.calcsize(FRAME_FMT)
MAGIC = 0xABCD
# ================= CRC ====================
def crc16_xor(data: bytes) -> int:
c = 0
for b in data:
c ^= b
return c & 0xFFFF
# ================= SERIAL =================
ser = serial.Serial(PORT, BAUD, timeout=1)
buffer = bytearray()
start_wall_time = None
start_ts_us = None
print("Listening...")
with open(OUT_FILE, "w", encoding="utf-8") as f:
while True:
buffer += ser.read(1024)
while len(buffer) >= FRAME_SIZE:
# ricerca MAGIC (0xABCD little-endian)
if buffer[0] != 0xCD or buffer[1] != 0xAB:
buffer.pop(0)
continue
frame = buffer[:FRAME_SIZE]
buffer = buffer[FRAME_SIZE:]
magic, ts_us, *imu, crc = struct.unpack(FRAME_FMT, frame)
if crc16_xor(frame[:-2]) != crc:
continue
# tempo base
if start_wall_time is None:
start_wall_time = datetime.now()
start_ts_us = ts_us
delta_us = ts_us - start_ts_us
ts = start_wall_time + timedelta(microseconds=delta_us)
imu1 = imu[:6]
imu2 = imu[6:]
line = (
f"{ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}"
f"|1:{','.join(map(str, imu1))}"
f"|2:{','.join(map(str, imu2))}\n"
)
f.write(line)
f.flush() # rimuovi se vuoi più performance
print(line.strip())
@@ -0,0 +1,92 @@
import serial
import struct
from datetime import datetime, timedelta
# ================= CONFIG =================
PORT = "COM17" # <-- cambia
BAUD = 2000000
OUT_FILE = "imu_log.txt"
# Formato frame ESP32 (raw)
FRAME_FMT = "<H I 6h 6h H" # magic, ts_us, imu1 6x int16, imu2 6x int16, crc
FRAME_SIZE = struct.calcsize(FRAME_FMT)
MAGIC_BYTES = b'\xCD\xAB'
# Conversione accelerometro e giroscopio
ACC_LSB_PER_G = 2048.0
G_CONST = 9.80665
GYRO_LSB_PER_DPS = 16.4
DEG2RAD = 0.017453292519943295
# ================= CRC ====================
def crc16_xor(data: bytes) -> int:
c = 0
for b in data:
c ^= b
return c & 0xFFFF
# ================= SERIAL =================
ser = serial.Serial(PORT, BAUD, timeout=1)
buffer = bytearray()
start_wall_time = None
start_ts_us = None
print("Listening...")
def convert_acc(raw):
return round(((raw / ACC_LSB_PER_G) * G_CONST)/10, 2)
def convert_gyro(raw):
return round((raw / GYRO_LSB_PER_DPS) * DEG2RAD, 2)
with open(OUT_FILE, "w", encoding="utf-8") as f:
while True:
buffer += ser.read(1024)
while True:
idx = buffer.find(MAGIC_BYTES)
if idx == -1:
buffer.clear()
break
if idx > 0:
buffer = buffer[idx:]
if len(buffer) < FRAME_SIZE:
break
frame = buffer[:FRAME_SIZE]
buffer = buffer[FRAME_SIZE:]
magic, ts_us, *imu_raw, crc = struct.unpack(FRAME_FMT, frame)
if crc16_xor(frame[:-2]) != crc:
print("CRC error (resync)")
continue
# Base timestamp
if start_wall_time is None:
start_wall_time = datetime.now()
start_ts_us = ts_us
delta_us = ts_us - start_ts_us
ts = start_wall_time + timedelta(microseconds=delta_us)
# Split raw dati
imu1_raw = imu_raw[:6]
imu2_raw = imu_raw[6:]
# Conversione in m/s² e rad/s
imu1 = [convert_acc(imu1_raw[0]), convert_acc(imu1_raw[1]), convert_acc(imu1_raw[2]),
convert_gyro(imu1_raw[3]), convert_gyro(imu1_raw[4]), convert_gyro(imu1_raw[5])]
imu2 = [convert_acc(imu2_raw[0]), convert_acc(imu2_raw[1]), convert_acc(imu2_raw[2]),
convert_gyro(imu2_raw[3]), convert_gyro(imu2_raw[4]), convert_gyro(imu2_raw[5])]
line = (
f"{ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}"
f"|1,{','.join(f'{v:.2f}' for v in imu1)}"
f"|2,{','.join(f'{v:.2f}' for v in imu2)}\n"
)
f.write(line)
f.flush()
print(line.strip())
@@ -0,0 +1,25 @@
import serial
from datetime import datetime
PORT = "COM3" # oppure "/dev/ttyUSB0"
BAUDRATE = 115200
LOG_FILE = "serial_log.txt"
ser = serial.Serial(PORT, BAUDRATE, timeout=1)
print("In ascolto sulla seriale... Ctrl+C per uscire")
with open(LOG_FILE, "a", encoding="utf-8") as f:
try:
while True:
line = ser.readline().decode(errors="ignore").strip()
if line:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
out = f"[{timestamp}] {line}"
print(out)
f.write(out + "\n")
f.flush()
except KeyboardInterrupt:
print("\nChiusura...")
finally:
ser.close()
@@ -0,0 +1,32 @@
import serial
import struct
import time
# configurazione porta
PORT = 'COM3' # cambia se serve
BAUD = 921600
# struttura Sample = 1 uint32 + 2 IMUData
# IMUData = 6 int16
# Formato struct: < = little-endian
fmt = '<I6h6h' # ts, imu1(6h), imu2(6h)
sample_size = struct.calcsize(fmt)
ser = serial.Serial(PORT, BAUD, timeout=1)
print(f"Listening on {PORT}...")
try:
while True:
data = ser.read(sample_size)
if len(data) != sample_size:
continue
s = struct.unpack(fmt, data)
ts = s[0]
imu1 = s[1:7]
imu2 = s[7:13]
print(f"{ts} | 1:{imu1} | 2:{imu2}")
except KeyboardInterrupt:
ser.close()
print("Closed")
@@ -0,0 +1,39 @@
import serial
import struct
# ---------------- CONFIG ----------------
PORT = 'COM3' # aggiorna con la tua COM
BAUD = 921600
fmt = '<I6h6h' # ts, imu1(6h), imu2(6h)
sample_size = struct.calcsize(fmt)
# ---------------- INIT ------------------
ser = serial.Serial(PORT, BAUD, timeout=1)
print(f"Listening on {PORT}...")
start_ts = None # primo timestamp ricevuto
try:
while True:
data = ser.read(sample_size)
if len(data) != sample_size:
continue # pacchetto incompleto
# ---- unpack del pacchetto ----
s = struct.unpack(fmt, data)
ts = s[0] # ts dell'ESP32 in microsecondi
imu1 = s[1:7]
imu2 = s[7:13]
# ---- calcolo timestamp relativo ----
if start_ts is None:
start_ts = ts
rel_time = (ts - start_ts) / 1_000_000 # in secondi
# ---- stampa dati ----
print(f"{rel_time:.6f}s | 1:{imu1} | 2:{imu2}")
except KeyboardInterrupt:
ser.close()
print("Closed")
@@ -0,0 +1,46 @@
import serial
import struct
import datetime
import time
# ---------------- CONFIG ----------------
PORT = 'COM3' # aggiorna con la tua COM
BAUD = 921600
fmt = '<I6h6h' # ts, imu1(6h), imu2(6h)
sample_size = struct.calcsize(fmt)
# ---------------- INIT ------------------
ser = serial.Serial(PORT, BAUD, timeout=1)
print(f"Listening on {PORT}...")
start_ts = None
start_time = None # tempo assoluto allinizio
try:
while True:
data = ser.read(sample_size)
if len(data) != sample_size:
continue # pacchetto incompleto
# ---- unpack del pacchetto ----
s = struct.unpack(fmt, data)
ts = s[0] # ts dell'ESP32 in microsecondi
imu1 = s[1:7]
imu2 = s[7:13]
# ---- inizializza riferimento tempo assoluto ----
if start_ts is None:
start_ts = ts
start_time = datetime.datetime.now()
# ---- calcola tempo assoluto basato sul ts progressivo ----
delta_us = ts - start_ts
abs_time = start_time + datetime.timedelta(microseconds=delta_us)
# ---- stampa dati con timestamp leggibile ----
print(f"{abs_time.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]} | 1:{imu1} | 2:{imu2}")
except KeyboardInterrupt:
ser.close()
print("Closed")
@@ -0,0 +1,72 @@
import serial
import struct
import datetime
import csv
PORT = 'COM3'
BAUD = 921600
MAGIC = 0xABCD
FRAME_FMT = '<HI6h6hH'
FRAME_SIZE = struct.calcsize(FRAME_FMT)
def crc16(data: bytes) -> int:
c = 0
for b in data:
c ^= b
return c
ser = serial.Serial(PORT, BAUD, timeout=1)
buffer = bytearray()
start_ts = None
start_time = None
csv_file = open('imu_log.csv', 'w', newline='')
writer = csv.writer(csv_file)
writer.writerow([
'timestamp',
'imu1_ax','imu1_ay','imu1_az','imu1_gx','imu1_gy','imu1_gz',
'imu2_ax','imu2_ay','imu2_az','imu2_gx','imu2_gy','imu2_gz'
])
print("Listening...")
try:
while True:
buffer += ser.read(512)
while len(buffer) >= FRAME_SIZE:
if buffer[0:2] != MAGIC.to_bytes(2, 'little'):
buffer.pop(0)
continue
frame = buffer[:FRAME_SIZE]
buffer = buffer[FRAME_SIZE:]
unpacked = struct.unpack(FRAME_FMT, frame)
crc_rx = unpacked[-1]
crc_calc = crc16(frame[:-2])
if crc_rx != crc_calc:
continue # frame corrotto
ts_us = unpacked[1]
if start_ts is None:
start_ts = ts_us
start_time = datetime.datetime.now()
abs_time = start_time + datetime.timedelta(
microseconds=(ts_us - start_ts)
)
writer.writerow([
abs_time.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],
*unpacked[2:14]
])
except KeyboardInterrupt:
csv_file.close()
ser.close()
print("Stopped")
File diff suppressed because it is too large Load Diff
+47
View File
@@ -0,0 +1,47 @@
import serial
import struct
import math
# --- impostazioni ---
G = 9.80665
ACC_LSB = 2048.0
GYRO_LSB = 16.4
def acc_raw_to_ms2(raw):
return (raw / ACC_LSB) * G
def gyro_raw_to_rad(raw):
return (raw / GYRO_LSB) * (math.pi / 180.0)
# apri seriale
ser = serial.Serial('COM8', 2000000)
frame_format = '<HIhhhhhhHH' # magic, ts, imu1(ax..gz), imu2(ax..gz), crc
frame_size = struct.calcsize(frame_format)
while True:
buf = ser.read(frame_size)
if len(buf) != frame_size:
continue
unpacked = struct.unpack(frame_format, buf)
magic, ts = unpacked[0], unpacked[1]
imu1_raw = unpacked[2:8]
imu2_raw = unpacked[8:14]
# conversione accelerometro e giroscopio
imu1 = [round(acc_raw_to_ms2(imu1_raw[0]), 2),
round(acc_raw_to_ms2(imu1_raw[1]), 2),
round(acc_raw_to_ms2(imu1_raw[2]), 2),
round(gyro_raw_to_rad(imu1_raw[3]), 2),
round(gyro_raw_to_rad(imu1_raw[4]), 2),
round(gyro_raw_to_rad(imu1_raw[5]), 2)]
imu2 = [round(acc_raw_to_ms2(imu2_raw[0]), 2),
round(acc_raw_to_ms2(imu2_raw[1]), 2),
round(acc_raw_to_ms2(imu2_raw[2]), 2),
round(gyro_raw_to_rad(imu2_raw[3]), 2),
round(gyro_raw_to_rad(imu2_raw[4]), 2),
round(gyro_raw_to_rad(imu2_raw[5]), 2)]
print(f"t={ts} imu1={imu1} imu2={imu2}")
+180
View File
@@ -0,0 +1,180 @@
#!/usr/bin/python3
import serial
import time
import json
import base64
import tarfile
import paho.mqtt.client as mqtt
import tempfile
import os
import threading
import socket
from datetime import datetime, timedelta
import logging
import sys
import struct
# === CONFIG LOGGING ===
logging.basicConfig(
level=logging.INFO,
format="%(levelname)s | %(message)s",
stream=sys.stdout
)
# === CONFIG ===
SERIAL_PORTS = ["/dev/esp_1", "/dev/esp_2", "/dev/esp_3", "/dev/esp_4"] # aggiungi altre se servono
BAUDRATE = 2000000
DURATION = 300
CLIENT_ID = socket.gethostname()
BROKER = "kiot-mqtts.pal.it"
PORT = 8883
TOPIC = "paliot/devs"
MAX_RETRIES = 30
USERNAME = "svcEMQXPortal"
PASSWORD = "n$IYAnkYCG7M#7zcJod23OS#"
STARTDATETIME = datetime.utcnow().isoformat() + "Z"
# === BIN FRAME CONFIG ===
FRAME_FMT = "<H I 6h 6h H"
FRAME_SIZE = struct.calcsize(FRAME_FMT)
MAGIC = 0xABCD
# === UTILS ===
def crc16_xor(data: bytes) -> int:
c = 0
for b in data:
c ^= b
return c & 0xFFFF
def reboot_machine():
logging.critical(">> Riavvio macchina per mancanza connessione")
os.system("reboot")
# === SERIAL CAPTURE (BINARIO → LOG TESTO) ===
def capture_serial(port, output_dir):
log_path = os.path.join(output_dir, f"{os.path.basename(port)}.log")
buffer = bytearray()
start_wall_time = None
start_ts_us = None
try:
with serial.Serial(port, BAUDRATE, timeout=1) as ser, \
open(log_path, "w", encoding="utf-8") as f:
start = time.time()
while time.time() - start < DURATION:
buffer += ser.read(1024)
while len(buffer) >= FRAME_SIZE:
if buffer[0] != 0xCD or buffer[1] != 0xAB:
buffer.pop(0)
continue
frame = buffer[:FRAME_SIZE]
buffer = buffer[FRAME_SIZE:]
magic, ts_us, *imu, crc = struct.unpack(FRAME_FMT, frame)
if crc16_xor(frame[:-2]) != crc:
continue
if start_wall_time is None:
start_wall_time = datetime.utcnow()
start_ts_us = ts_us
delta_us = ts_us - start_ts_us
ts = start_wall_time + timedelta(microseconds=delta_us)
imu1 = imu[:6]
imu2 = imu[6:]
line = (
f"{ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}"
f"|1,{','.join(map(str, imu1))}"
f"|2,{','.join(map(str, imu2))}\n"
)
f.write(line)
except Exception as e:
logging.error(f"[{port}] Errore seriale: {e}")
return log_path
# === FILE UTILS ===
def compress_directory(directory):
tar_path = os.path.join(directory, "logs.tar.gz")
with tarfile.open(tar_path, "w:gz") as tar:
for filename in os.listdir(directory):
if filename.endswith(".log"):
tar.add(os.path.join(directory, filename), arcname=filename)
return tar_path
def file_to_base64(file_path):
with open(file_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
def build_payload(encoded_log):
return {
"clientId": CLIENT_ID,
"dateTime": STARTDATETIME,
"log": encoded_log
}
# === MQTT SENDER ===
def send_mqtt(payload):
retries = 0
while retries < MAX_RETRIES:
try:
client = mqtt.Client(client_id=CLIENT_ID)
client.username_pw_set(USERNAME, PASSWORD)
client.tls_set()
client.connect(BROKER, PORT, 60)
client.loop_start()
client.publish(TOPIC, json.dumps(payload))
client.loop_stop()
client.disconnect()
logging.info(">> Payload MQTT inviato con successo.")
return True
except Exception as e:
retries += 1
logging.warning(f"MQTT publish failed ({retries}/{MAX_RETRIES}): {e}")
if retries == MAX_RETRIES:
reboot_machine()
return False
time.sleep(5)
return False
# === MAIN ===
def main():
temp_dir = tempfile.mkdtemp(prefix="serial_logs_")
threads = []
for port in SERIAL_PORTS:
t = threading.Thread(target=capture_serial, args=(port, temp_dir))
t.start()
threads.append(t)
for t in threads:
t.join()
logging.info(">> Tutte le seriali hanno completato la registrazione.")
tar_file = compress_directory(temp_dir)
encoded = file_to_base64(tar_file)
payload = build_payload(encoded)
send_mqtt(payload)
for filename in os.listdir(temp_dir):
os.remove(os.path.join(temp_dir, filename))
os.rmdir(temp_dir)
logging.info(">> Operazione completata.")
if __name__ == "__main__":
main()
+22
View File
@@ -0,0 +1,22 @@
piLogger.py codice aggiornato del serialLogger presente nella rpi in impianto
mentre in PIO/Projects c'è il nuovo fw per le esp, per ottenere un tempo di resa del dato ogni 2ms
result line
2026-02-10 14:43:15.566|1,496,-292,16500,-219,19,132|2,168,-16700,-864,105,59,-162
[
"2026-02-10 14:43:15.566", timestamp utc
(
[
1, 'OrientationId'
496, 'ax'
-292, 'ay'
16500, 'az'
-219, 'gx'
19, 'gy'
132 'gz'
]
),
(2, [168,-16700,-864,105,59,-162])
]