Ciao a tutti, sono alle prese con un progetto domotico e volevo avere la possibilità di accendere e spegnere un rele tramite arduino.
Il progetto è così composto.
Raspberry pi che fa da web server
Arduino uno (a) collegato usb al raspberry pi che legge i comandi da seriale
Altra scheda arduino uno (b) con collegati un sensore di temperatura, un rele e un nrf24l01 che comunica senza fili con arduino uno (a).
Su raspberry ho caricato uno script in python che viene eseguito ogni 3 minuti e verifica su un database mysql se il rele dev'essere acceso o spento. In base a questo valore invia via seriale sulla porta di arduino un valore 'H' se acceso e 'L' se spento. Arduino leggendo il valore accende o spegne il rele. Il tutto funziona a meraviglia a parte un piccolo problema.
Quando arduino legge da seriale tramite raspberry (una volta ogni 3 minuti) la lettura provoca lo spegnimento momentaneo del relè.. che poi in base al valore letto si riaccende o si rispegne. E' risolvibile tutto ciò? Oppure devo cambiare strada?
import serial
import string
import MySQLdb
import pprint
db = MySQLdb.connect(host="localhost", # your host, usually localhost
user="root", # your username
passwd="pass", # your password
db="arduino") # name of the data base
cur = db.cursor()
arduinoPort = '/dev/ttyACM1' #check in the /dev folder the Arduino Serial Port
ser = serial.Serial()
ser.setPort(arduinoPort) #boundRate 9600 automatically set
ser.setTimeout(2)
try:
ser.open()
except:
print('Port Error!')
else:
for i in range (6):
ardString = ser.readline()
#print(ardString)
valueMatrix= ardString.split(' ')
if len(valueMatrix)> 1 :
pprint.pprint(valueMatrix)
#pprint.pprint(valueMatrix)
projectId = valueMatrix[0]
value = valueMatrix[1]
#inserire variabile sql che cambia con lo stato della stufa e determina se H o L
cur.execute('SELECT `cucina`, `camera` FROM `stati` WHERE 1')
a=cur.fetchone()
if a[0] == 1:
print a[0]
ser.write('H');
else:
ser.write('L');
#print("value received:"+string+ " interpreted as: project Id = "+projectId+" and value = "+value)
cur.execute('INSERT INTO ard_project_data (value) VALUES ("'+value+'")')
db.commit()
ser.close()
print('connection closed')
db.close()
print('database closed')
print('end')
questo è il codice caricato nell'arduino uno collegata a RPi:
Ho cambiato da float a int come mi hai consigliato ma il problema non è quello.
Pare come che quando vi sia la lettura in seriale il tutto si ferma e il rele sospende il suo funzionamento per poi giustamente tornare a funzionare se nel database il valore del campo è su '1' o spegnersi se è su '0'.
python è un linguaggio posizionale, se il tuo codice ha la stessa indentazione di quello messo nel post all'esecuzione della pprint veniva chiuso l'if ... lascia la pprint ma indenta bene ....
no purtroppo non è un problema di indentatura.. e non si è ancora risolto.. sembrava funzionare ma ogni tanto il rele si spegne per poi riaccendersi..
ragionando il rele si attiva o disattiva in base a ciò che python scrive.. se scrive H si attiva mentre se scrive L si disattiva. Questo valore viene preso dal database. Se nel database c'è 1 python stampa H -> arduino uno (a) legge H e quindi invia all'arduino remoto un valore 1 (in questo caso). Verificando tutti i passaggi ho notato che ogni tanto il valore che arriva ad arduino remoto è pari a zero. Nel database tuttavia il valore è 1 quindi il problema è più avanti. Python scriverà sempre H però lo scrive solo una volta al minuto quando si esegue lo script. Da qui deduco che il problema è un problema di sincronia.. ovvero ogni tanto arduino legge H mentre ogni tanto non legge niente e quindi molto probabilmente invia 0 al posto di uno.
Si potrebbe supporre quindi che lo script python debba sempre essere in esecuzione.. ma se provo ad eseguire in continuazione lo script il risultato è identico e il relè ha una certa intermittenza.
A questo punto credo che il problema sia legato al trasferimento del dato che determina lo stato del rele (dati2). Perchè andando ad aprire uno schermo seriale ogni tanto stampa zero anzichè uno sulla board remota pur stampando 1 sul rele principale. Secondo voi può essere che ogni tanto si perdano dati nel trasferimento? Ho anche aggiunto dei delay ma questo non fa altro che ritardare gli intervalli di spegnimento del rele ovviamente.
Non riesco a risalire alla libreria che stai usando per i moduli nrlf24 .. in generale io controllerei i valori di ritorno di transmitter.read() e
transmitter.rxPL(dati2)
quello che succede probabilmente è che fai una read e non viene ricevuto nulla, tu ignori questo fatto e leggi da un buffer vuoto (probabilmente 0)
Io controllerei la libreria per vedere che valori ritornano le read, se non ne ritornano nessuno cambierei la logica di acceso-spento in 1 e 2 invece che 0 e 1, così nel caso in cui tu leggi 0 ignori il valore e vai avanti.
Inoltre, perchè mandi il valore via seriale/rf se non è cambiato ?
madmatt71:
Non riesco a risalire alla libreria che stai usando per i moduli nrlf24 .. in generale io controllerei i valori di ritorno di transmitter.read() e
transmitter.rxPL(dati2)
quello che succede probabilmente è che fai una read e non viene ricevuto nulla, tu ignori questo fatto e leggi da un buffer vuoto (probabilmente 0)
Io controllerei la libreria per vedere che valori ritornano le read, se non ne ritornano nessuno cambierei la logica di acceso-spento in 1 e 2 invece che 0 e 1, così nel caso in cui tu leggi 0 ignori il valore e vai avanti.
Inoltre, perchè mandi il valore via seriale/rf se non è cambiato ?
Ho modificato lo sketch del trasmettitore e ora funziona tutto liscio! Il relè non perde più colpi ma è comandato a dovere!
Il problema è come dicevi tu madmatt71 il fatto che ogni tanto in ricezione veniva letto senza ricevere nulla e quindi lo zero provocava lo spegnimento. Cambiando la variabile da 0 a 2 tutto si è risolto, ogni tanto comunque viene letto zero ma questo non provoca nulla al processo di controllo del relè!