SENSORE CJMCU-MS5540C

Buongiorno a tutti,
vi chedo aiuto per il collegamento di arduino con sensore di profondita acqua MS5540C
la prima domanda che volevo porre, ma questo sensore calibrato nel modo giusto segnala la profondita in acqua in cui si trova anche in mare aperto o deve per forza trovarsi in un contenitore d'acqua?
e poi qule tipo di codice dovrei utilizzare per far si che arduino azioni una pompa tramite rele in base ai dati di profondita rilevati dal sensore?
Mi spiego meglio vorrei far in modo che arduino se il valore del sensore scenda sotto una certa profondita
azioni un rele.
E poi che tipo di calcolo dovro fare per trasformare la pressione che rileva il sensore in cm di profondita?
Grazie in anticipo per chi possa aiutarmi.

Veramente il primo problema ch vedo è ... come lo colleghi sott'acqua ... ::slight_smile:

Difatti, la zona sensibile del sensore è protetta da un gel adatto al contatto con l'acqua, ma ... tutto il resto del circuito? Hai già in mente un qualche cosa per avere SOLO l'area sensibile esposta e tutto il resto isolato (anche in caso di pressioni notevoli)?

Per il resto, il datasheet del prodotto è piuttosto chiaro e spiega molto bene cme ricevere i dati ed effettuare i calcoli (che, non sonio solo funzione della pressione, ma della temperatura del sensore) ... vedi pag. 11/20 che da proprio il diagramma di cosa fare.

Guglielmo

... una volta risolto il problema dell'isolamento completo dall'acqua di tutto ciò che non è l'area sensibile (quella protetta con il gel), magari questo vecchio articolo ti può aiutare (vd. allegato).

Guglielmo

water_depth_sensor_MS5540C_Arduino_tutorial.pdf (151 KB)

grazie gpb01 per la tua pronta risposta (speravo che mi davi proprio tu una risposta in quanto nel corso delle mie ricerche ho notato che hai aiutato tanti in svariati problemi).
Detto ciò per l'isolamento del sensore e cablaggio nessun problema.
In quanto al link che mi hai inviato l'ho gia visto ma in tutta sincerità ho vari problemi a modificarlo.
infatti volevo proprio partire da li, eliminando altre letture tipo temperatura (per eliminare qualche collegamento se possibile) e il solo valore della pressione in quanto per il progetto miniaturizzato ho acquistato un arduino beetle e dovrei poi aggiungerci un sensore gy-521 con cui non ho nessun problema (gia usato per un progetto mano robotica movimento polso) ed ho bisogno di pochi collegamenti.
Ma sopratutto com aggiungere codice else per rele in base ai valori profondita (in cm) nel senso che in base alla profondita ed al tempo scatti il rele.
Spero di non essere stato toppo lungo nel discorso e grazie ancora per il tuo tempo

SABATINOCC:
... eliminando altre letture tipo temperatura (per eliminare qualche collegamento se possibile) e il solo valore della pressione in quanto per il progetto miniaturizzato ho acquistato ...

Non puoi (se ti studi il datasheet vedi che l'inidcazione della pressione è funzione della temperatura del sensore) e NON hai bisogno di cavi aggiuntivi ... quel sensore lavora in SPI e tutti i dati (temperatura inclusa) viaggiano sul detto bus.

Guglielmo

Dal datasheet (che ripeto, va studiato), pagina 9/20 ...

GENERAL
The MS5540C consists of a piezo-resistive sensor and a sensor interface IC. The main function of the MS5540C is to convert the uncompensated analogue output voltage from the piezo-resistive pressure sensor to a 16-bit digital value, as well as providing a 16-bit digital value for the temperature of the sensor.

Measured pressure (16-bit) “D1”
Measured temperature (16-bit) “D2”

As the output voltage of a pressure sensor is strongly dependent on temperature and process tolerances, it is necessary to compensate for these effects. This compensation procedure must be performed by software using an external microcontroller.

Guglielmo

Allora grazie ai vostri suggerimenti ed esempi vari sono riuscito a creare un esempio base
da dove partire.
Non mi da errore di compilazione ma non so se possa funzionare....(sto costruendo la parte Hardware)
poi ultima modifica sarebbe quella di aggiungere delle variabili in cui se i valori persistono per un tot
di secondi si azioni il relè....
grazie in anticipo per i vostri suggerimenti.

#include <SPI.h>
#include <Wire.h>
#include <Servo.h>
#define MPU 0x68  // I2C address of the MPU-6050
#define SOLEINODE 2
double AcX,AcY,AcZ;
int Pitch, Roll;
int clock = 9;
void resetsensor() //this function keeps the sketch a little shorter
{
SPI.setDataMode(SPI_MODE0);
SPI.transfer(0x15);
SPI.transfer(0x55);
SPI.transfer(0x40);
}
void setup() {
Serial.begin(9600);
init_MPU(); // Inizializzazione MPU6050
SPI.begin(); //see SPI library details on arduino.cc for details
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz
pinMode(clock, OUTPUT);
pinMode(SOLEINODE, OUTPUT);
delay(100);
}
void loop() {
  FunctionsMPU(); // Acquisisco assi AcX, AcY, AcZ.
 
  Roll = FunctionsPitchRoll(AcX, AcY, AcZ);   //Calcolo angolo Roll
  Pitch = FunctionsPitchRoll(AcY, AcX, AcZ);  //Calcolo angolo Pitch
   
  Serial.print("Pitch: "); Serial.print(Pitch);
  Serial.print("\t");
  Serial.print("Roll: "); Serial.print(Roll);
  Serial.print("\n");
  }
 
void init_MPU(){
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  delay(1000);
}
 
//Funzione per il calcolo degli angoli Pitch e Roll
double FunctionsPitchRoll(double A, double B, double C){
  double DatoA, DatoB, Value;
  DatoA = A;
  DatoB = (B*B) + (C*C);
  DatoB = sqrt(DatoB);
 
  Value = atan2(DatoA, DatoB);
  Value = Value * 180/3.14;
 
  return (int)Value;
}
 
//Funzione per l'acquisizione degli assi X,Y,Z del MPU6050
void FunctionsMPU(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,6,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
 
TCCR1B = (TCCR1B & 0xF8) | 1 ; //generates the MCKL signal
analogWrite (clock, 128) ;
resetsensor();//resets the sensor - caution: afterwards mode = SPI_MODE0!
//Calibration word 1
unsigned int word1 = 0;
unsigned int word11 = 0;
SPI.transfer(0x1D); //send first byte of command to get calibration word 1
SPI.transfer(0x50); //send second byte of command to get calibration word 1
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
word1 = SPI.transfer(0x00); //send dummy byte to read first byte of word
word1 = word1 << 8; //shift returned byte
word11 = SPI.transfer(0x00); //send dummy byte to read second byte of word
word1 = word1 | word11; //combine first and second byte of word
resetsensor();//resets the sensor
//Calibration word 2; see comments on calibration word 1
unsigned int word2 = 0;
byte word22 = 0;
SPI.transfer(0x1D);
SPI.transfer(0x60);
SPI.setDataMode(SPI_MODE1);
word2 = SPI.transfer(0x00);
word2 = word2 <<8;
word22 = SPI.transfer(0x00);
word2 = word2 | word22;
resetsensor();//resets the sensor
//Calibration word 3; see comments on calibration word 1
unsigned int word3 = 0;
byte word33 = 0;
SPI.transfer(0x1D);
SPI.transfer(0x90);
SPI.setDataMode(SPI_MODE1);
word3 = SPI.transfer(0x00);
word3 = word3 <<8;
word33 = SPI.transfer(0x00);
word3 = word3 | word33;
resetsensor();//resets the sensor
//Calibration word 4; see comments on calibration word 1
unsigned int word4 = 0;
byte word44 = 0;
SPI.transfer(0x1D);
SPI.transfer(0xA0);
SPI.setDataMode(SPI_MODE1);
word4 = SPI.transfer(0x00);
word4 = word4 <<8;
word44 = SPI.transfer(0x00);
word4 = word4 | word44;
long c1 = word1 << 1;
long c2 = ((word3 & 0x3F) >> 6) | ((word4 & 0x3F));
long c3 = (word4 << 6) ;
long c4 = (word3 << 6);
long c5 = (word2 << 6) | ((word1 & 0x1) >> 10);
long c6 = word2 & 0x3F;
resetsensor();//resets the sensor
//Temperature:
unsigned int tempMSB = 0; //first byte of value
unsigned int tempLSB = 0; //last byte of value
unsigned int D2 = 0;
SPI.transfer(0x0F); //send first byte of command to get temperature value
SPI.transfer(0x20); //send second byte of command to get temperature value
delay(35); //wait for conversion end
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
tempMSB = tempMSB << 8; //shift first byte
tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
D2 = tempMSB | tempLSB; //combine first and second byte of value
resetsensor();//resets the sensor
//Pressure:
unsigned int presMSB = 0; //first byte of value
unsigned int presLSB =0; //last byte of value
unsigned int D1 = 0;
SPI.transfer(0x0F); //send first byte of command to get pressure value
SPI.transfer(0x40); //send second byte of command to get pressure value
delay(35); //wait for conversion end
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
presMSB = presMSB << 8; //shift first byte
presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
D1 = presMSB | presLSB;
const long UT1 = (c5 * 8) + 20224;
const long dT =(D2 - UT1);
const long TEMP = 200 + ((dT * (c6 + 50))/1024);
const long OFF = (c2*4) + (((c4 - 512) * dT)/4096);
const long SENS = c1 + ((c3 * dT)/1024) + 24576;
long PCOMP = ((((SENS * (D1 - 7168))/16384)- OFF)/32)+250;
float TEMPREAL = TEMP/10;
Serial.print("pressure = "); Serial.print(" - ");
Serial.print(PCOMP);
Serial.println(" mbar");
const long dT2 = dT - ((dT >> 7 * dT >> 7) >> 3);
const float TEMPCOMP = (200 + (dT2*(c6+100) >>11))/10;
Serial.print("temperature = ");
Serial.print(TEMPCOMP);
Serial.println(" °C");
Serial.println("************************************");

if(" mbar" >= 5)
{
digitalWrite(SOLEINODE, HIGH);
}
if(Pitch = 0)
{
digitalWrite(SOLEINODE, HIGH);
}
if(Roll = 0)
{
digitalWrite(SOLEINODE, HIGH);
}
delay(1000);
}

Ho iniziato a fare delle modifiche studiando un pò e con soddisfazione avendo creato anche la parte hardware
sono riuscito ad avere i primi risultati positivi.
per ora uso la pressione del sensore non in acqua, però andando a modificare i dati sia del sensore acqua che del giroscopio con la funzione "if" riesco a far attivare il motore in base ai dati raccolti.
Ora viene la mia richiesta "banale magari" ho bisogno di far si che si attivi il motore solo se si verifichino le condizioni in cui entrambi i sensori superino la soglia stabilita per un tempo di 5 secondi, altrimenti resti spento, quindi non se i valori superano la soglia ma se la superano per un tempo di 5 secondi.
grazie a tutti in anticipo....

#include <SPI.h>
#include <Wire.h>
#define MPU 0x68  // I2C address of the MPU-6050

double AcX,AcY,AcZ;
int Roll;
int clock = 9;
int valvola = 7;
void resetsensor() //this function keeps the sketch a little shorter
{
SPI.setDataMode(SPI_MODE0);
SPI.transfer(0x15);
SPI.transfer(0x55);
SPI.transfer(0x40);
}
void setup() {
Serial.begin(9600);
init_MPU(); // Inizializzazione MPU6050
SPI.begin(); //see SPI library details on arduino.cc for details
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz
pinMode(clock, OUTPUT);
pinMode (7, OUTPUT);
delay(1000);
}

void init_MPU(){
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  delay(1000);
}
 
//Funzione per il calcolo degli angoli Pitch e Roll
double FunctionsPitchRoll(double A, double B, double C){
  double DatoA, DatoB, Value;
  DatoA = A;
  DatoB = (B*B) + (C*C);
  DatoB = sqrt(DatoB);
  
  Value = atan2(DatoA, DatoB);
  Value = Value * 180/3.14;
  
  return (int)Value;
}
 
//Funzione per l'acquisizione degli assi X,Y,Z del MPU6050
void FunctionsMPU(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,6,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
}

void loop()
{
  FunctionsMPU(); // Acquisisco assi AcX, AcY, AcZ.
    
  Roll = FunctionsPitchRoll(AcX, AcY, AcZ);   //Calcolo angolo Roll
 
  int ValvolaRoll = map(Roll, -90, 90, 0, 179);
  
TCCR1B = (TCCR1B & 0xF8) | 1 ; //generates the MCKL signal
analogWrite (clock, 128) ;
resetsensor();//resets the sensor - caution: afterwards mode = SPI_MODE0!
//Calibration word 1
unsigned int word1 = 0;
unsigned int word11 = 0;
SPI.transfer(0x1D); //send first byte of command to get calibration word 1
SPI.transfer(0x50); //send second byte of command to get calibration word 1
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
word1 = SPI.transfer(0x00); //send dummy byte to read first byte of word
word1 = word1 << 8; //shift returned byte
word11 = SPI.transfer(0x00); //send dummy byte to read second byte of word
word1 = word1 | word11; //combine first and second byte of word
resetsensor();//resets the sensor
//Calibration word 2; see comments on calibration word 1
unsigned int word2 = 0;
byte word22 = 0;
SPI.transfer(0x1D);
SPI.transfer(0x60);
SPI.setDataMode(SPI_MODE1);
word2 = SPI.transfer(0x00);
word2 = word2 <<8;
word22 = SPI.transfer(0x00);
word2 = word2 | word22;
resetsensor();//resets the sensor
//Calibration word 3; see comments on calibration word 1
unsigned int word3 = 0;
byte word33 = 0;
SPI.transfer(0x1D);
SPI.transfer(0x90);
SPI.setDataMode(SPI_MODE1);
word3 = SPI.transfer(0x00);
word3 = word3 <<8;
word33 = SPI.transfer(0x00);
word3 = word3 | word33;
resetsensor();//resets the sensor
//Calibration word 4; see comments on calibration word 1
unsigned int word4 = 0;
byte word44 = 0;
SPI.transfer(0x1D);
SPI.transfer(0xA0);
SPI.setDataMode(SPI_MODE1);
word4 = SPI.transfer(0x00);
word4 = word4 <<8;
word44 = SPI.transfer(0x00);
word4 = word4 | word44;
long c1 = word1 << 1;
long c2 = ((word3 & 0x3F) >> 6) | ((word4 & 0x3F));
long c3 = (word4 << 6) ;
long c4 = (word3 << 6);
long c5 = (word2 << 6) | ((word1 & 0x1) >> 10);
long c6 = word2 & 0x3F;
resetsensor();//resets the sensor
//Temperature:
unsigned int tempMSB = 0; //first byte of value
unsigned int tempLSB = 0; //last byte of value
unsigned int D2 = 0;
SPI.transfer(0x0F); //send first byte of command to get temperature value
SPI.transfer(0x20); //send second byte of command to get temperature value
delay(35); //wait for conversion end
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
tempMSB = tempMSB << 8; //shift first byte
tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
D2 = tempMSB | tempLSB; //combine first and second byte of value
resetsensor();//resets the sensor
//Pressure:
unsigned int presMSB = 0; //first byte of value
unsigned int presLSB =0; //last byte of value
unsigned int D1 = 0;
SPI.transfer(0x0F); //send first byte of command to get pressure value
SPI.transfer(0x40); //send second byte of command to get pressure value
delay(35); //wait for conversion end
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
presMSB = presMSB << 8; //shift first byte
presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
D1 = presMSB | presLSB;
const long UT1 = (c5 * 8) + 20224;
const long dT =(D2 - UT1);
const long TEMP = 200 + ((dT * (c6 + 50))/1024);
const long OFF = (c2*4) + (((c4 - 512) * dT)/4096);
const long SENS = c1 + ((c3 * dT)/1024) + 24576;
long PCOMP = ((((SENS * (D1 - 7168))/16384)- OFF)/32)+250;
float TEMPREAL = TEMP/10;
Serial.print("pressure = ");
Serial.print(PCOMP);
Serial.println(" mbar");
const long dT2 = dT - ((dT >> 7 * dT >> 7) >> 3);
const float TEMPCOMP = (200 + (dT2*(c6+100) >>11))/10;
Serial.print("Roll: "); Serial.print(Roll);
Serial.print("\n");
delay(1000);

   if (PCOMP > 12000)
   {digitalWrite(7, HIGH);}
   else if (Roll < -10)
   {digitalWrite(7, HIGH);}
   else
   {digitalWrite(7, LOW);}
  
 }
[\code]

Per queste cose devi studiarti come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... vedrai che alla fine ti sarà ben chiaro di come fare cose legate al "tempo" :wink:

Guglielmo

letti e studiati ma forse sono io che ragiono male....
stavo pensando di impostare il tempo ed i millis come lettura dal monitor seriale
e cioe quando serial.printl (Roll) supera -10 gradi per più di 5 secondi o serial.printl (PCOMP) supera i 1200 mbar per più di 5 secondi
in quanto i valori sono generati da processi complessi e non letti da un semplice pin (tipo pulsante)
....

Quando un qualche cosa supera un certo valore, alzi una flag per ricordartelo e ti segni il valore di millis() per quel qualche cosa ...
... ad ogni giro di loop (che ti ricordo gira in continuazione) guardi se c'è una qualche flag alzata, se si verifichi che la cosa associata sia sempre sopra il valore (altrimenti puoi anche rimettere a false la flag e non fare nulla). Se si, controlli che millis() attuale meno il valore che ti eri salvato sia maggiore o uguale al tempo che hai deciso e, se SI, sai cosa fare.

Più lungo a scrivere e spiegare che a codificare :smiley:

Guglielmo

Guglielmo grazie per la pronta risposta, ma il ragionamento ovvimente è valido e lo comprendo e saprei anche come fare con lettura analogica da un pin (A0, A4, etc.)
Ma non riesco a comprendere il come usarlo con lettura da serial.print...

questo il mio ragionamento.... guardando il codice postato precedentamente?:

void setup()

time=millis();
COMP>12200=millis();
Roll>-10=millis();
time_attesa=5000;

void loop()

time=millis();

if (time - (PCOMP>12200) >= time_attesa) 
{digitalWrite(7, HIGH);}
  else
   {digitalWrite(7, LOW);}

if (time - (Roll>-10) >= time_attesa) 
{digitalWrite(7, HIGH);}
  else
   {digitalWrite(7, LOW);}


scrivere condizione temporale in base alla lettura su serial.print

grazie ancora, resto in attesa vostre critiche... :confused:  :confused:

Prima di tutto NON usare simboli speciali nei nomi di costanti e variabili, quindi dimentica di usare '>', '<', ecc., solo caratteri alfanumerici e i caratteri '-' e '_' ... tutto il resto rende il codice difficilemente leggibile, crea confusione e, forse, in alcuni casi, potrebbe creare anche problemi ... ::slight_smile:

Detto questo, riprendi il mio post #10 e mettilo giù come diagramma di flusso ... solo dopo scrivi il codice ...

Guglielmo

ok ecco un riepilogo (sempre ad integrazione del primo codice postato)

sr=serial.print(Roll)
sp=serial.print(PCOMP)

if ((sr != srp) && (srp <= -10))
{
srp=sr;
millis_p=millis();
}
if ((sr != srp) && (srp >= -9))
{
srp=sr;
if (millis() - millis_prec >= 5000)
{
digitaWrite (7, HIGH);
}
else 
{
digitalWrite(7, LOW);
}


if ((sp != spp) && (spp >= 12200))
{
spp=sp;
millis_p=millis();
}
if ((sp != spp) && (spp <= 12199))
{
spp=sr;
if (millis() - millis_prec >= 5000)
{
digitaWrite (7, HIGH);
}
else 
{
digitalWrite(7, LOW);
}

in attesa considerazioni, grazie

Provo a spiegare meglio quello che ho scritto al post #10 ...

  1. flag1 = false; flag2 = false;
  2. verifico sensore1
  3. valore sensore1 superiore al limite?
    3.1 NO, flag1 = false;
    3.2 SI, se flag1 == false, allora flag1 = true e salvo il valore di millis() in una variabile1
    4 verifico sensore2
  4. valore sensore2 superiore al limite?
    5.1 NO, flag2 = false;
    5.2 SI, se flag2 == false, allora flag2 = true e salvo il valore di millis() in una variabile2
  5. flag1 == true ?
    6.1 NO, nulla di particolare
    6.2 SI, mi chiedo se da differenza tra millis() attuale meno il valore salvato in variabile1 supera il tempo massimo e, se SI, vedi tu che devi fare, se NO, nulla di particolare.
  6. flag2 == true ?
    7.1 NO, nulla di particolare
    7.2 SI, mi chiedo se da differenza tra millis() attuale meno il valore salvato in variabile2 supera il tempo massimo e, se SI, vedi tu che devi fare, , se NO, nulla di particolare.
  7. il loop() si ripete e deve tornare al punto 2. (il punto 1 va fuori del loop(), nel setup())

Se le due cose le devi invece controllare assieme, dovrai cambiare un po' i confronti e le azioni, ma la logica è quella.

Un po' più chiaro ora ?

Guglielmo

Ecco codice funzionante
grazie a tutti per l'aiuto.

#include <SPI.h>
#include <Wire.h>
#define MPU 0x68  // I2C address of the MPU-6050

double AcX,AcY,AcZ;
int Roll = 0;
int clock = 9;
int valvola = 7;
unsigned long time;
unsigned long time2;
boolean flag1 = false;
boolean flag2 = false;
void resetsensor() //this function keeps the sketch a little shorter


{
SPI.setDataMode(SPI_MODE0);
SPI.transfer(0x15);
SPI.transfer(0x55);
SPI.transfer(0x40);
}
void setup() {
Serial.begin(9600);
init_MPU(); // Inizializzazione MPU6050
SPI.begin(); //see SPI library details on arduino.cc for details
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz
pinMode(clock, OUTPUT);
pinMode (7, OUTPUT);
delay(1000);
}

void init_MPU(){
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  delay(1000);
}
 
//Funzione per il calcolo degli angoli Pitch e Roll
double FunctionsPitchRoll(double A, double B, double C){
  double DatoA, DatoB, Value;
  DatoA = A;
  DatoB = (B*B) + (C*C);
  DatoB = sqrt(DatoB);
  
  Value = atan2(DatoA, DatoB);
  Value = Value * 180/3.14;
  
  return (int)Value;
}
 
//Funzione per l'acquisizione degli assi X,Y,Z del MPU6050
void FunctionsMPU(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,6,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
}

void loop()
{
  FunctionsMPU(); // Acquisisco assi AcX, AcY, AcZ.
    
  Roll = FunctionsPitchRoll(AcX, AcY, AcZ);   //Calcolo angolo Roll
 
  int ValvolaRoll = map(Roll, -90, 90, 0, 179);
  
TCCR1B = (TCCR1B & 0xF8) | 1 ; //generates the MCKL signal
analogWrite (clock, 128) ;
resetsensor();//resets the sensor - caution: afterwards mode = SPI_MODE0!
//Calibration word 1
unsigned int word1 = 0;
unsigned int word11 = 0;
SPI.transfer(0x1D); //send first byte of command to get calibration word 1
SPI.transfer(0x50); //send second byte of command to get calibration word 1
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
word1 = SPI.transfer(0x00); //send dummy byte to read first byte of word
word1 = word1 << 8; //shift returned byte
word11 = SPI.transfer(0x00); //send dummy byte to read second byte of word
word1 = word1 | word11; //combine first and second byte of word
resetsensor();//resets the sensor
//Calibration word 2; see comments on calibration word 1
unsigned int word2 = 0;
byte word22 = 0;
SPI.transfer(0x1D);
SPI.transfer(0x60);
SPI.setDataMode(SPI_MODE1);
word2 = SPI.transfer(0x00);
word2 = word2 <<8;
word22 = SPI.transfer(0x00);
word2 = word2 | word22;
resetsensor();//resets the sensor
//Calibration word 3; see comments on calibration word 1
unsigned int word3 = 0;
byte word33 = 0;
SPI.transfer(0x1D);
SPI.transfer(0x90);
SPI.setDataMode(SPI_MODE1);
word3 = SPI.transfer(0x00);
word3 = word3 <<8;
word33 = SPI.transfer(0x00);
word3 = word3 | word33;
resetsensor();//resets the sensor
//Calibration word 4; see comments on calibration word 1
unsigned int word4 = 0;
byte word44 = 0;
SPI.transfer(0x1D);
SPI.transfer(0xA0);
SPI.setDataMode(SPI_MODE1);
word4 = SPI.transfer(0x00);
word4 = word4 <<8;
word44 = SPI.transfer(0x00);
word4 = word4 | word44;
long c1 = word1 << 1;
long c2 = ((word3 & 0x3F) >> 6) | ((word4 & 0x3F));
long c3 = (word4 << 6) ;
long c4 = (word3 << 6);
long c5 = (word2 << 6) | ((word1 & 0x1) >> 10);
long c6 = word2 & 0x3F;
resetsensor();//resets the sensor
//Temperature:
unsigned int tempMSB = 0; //first byte of value
unsigned int tempLSB = 0; //last byte of value
unsigned int D2 = 0;
SPI.transfer(0x0F); //send first byte of command to get temperature value
SPI.transfer(0x20); //send second byte of command to get temperature value
delay(35); //wait for conversion end
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
tempMSB = tempMSB << 8; //shift first byte
tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
D2 = tempMSB | tempLSB; //combine first and second byte of value
resetsensor();//resets the sensor
//Pressure:
unsigned int presMSB = 0; //first byte of value
unsigned int presLSB =0; //last byte of value
unsigned int D1 = 0;
SPI.transfer(0x0F); //send first byte of command to get pressure value
SPI.transfer(0x40); //send second byte of command to get pressure value
delay(35); //wait for conversion end
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
presMSB = presMSB << 8; //shift first byte
presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
D1 = presMSB | presLSB;
const long UT1 = (c5 * 8) + 20224;
const long dT =(D2 - UT1);
const long TEMP = 200 + ((dT * (c6 + 50))/1024);
const long OFF = (c2*4) + (((c4 - 512) * dT)/4096);
const long SENS = c1 + ((c3 * dT)/1024) + 24576;
long PCOMP = ((((SENS * (D1 - 7168))/16384)- OFF)/32)+250;
float TEMPREAL = TEMP/10;
Serial.print("pressure = ");
Serial.print(PCOMP);
Serial.println(" mbar");
const long dT2 = dT - ((dT >> 7 * dT >> 7) >> 3);
const float TEMPCOMP = (200 + (dT2*(c6+100) >>11))/10;
Serial.print("Roll: "); Serial.print(Roll);
Serial.print("\n");
delay(1000);


if (Roll > -10)
 {flag2 = false;}
if (flag2==false)
{flag2=true;
time2 = millis();
}
if (flag2==true && ((millis() - time2) > 5000))
{ digitalWrite (7, HIGH);
delay (1000);
digitalWrite (7, LOW);
}

if (PCOMP < 12000)
 {flag1 = false;}
if (flag1==false)
{flag1=true;
time = millis();
}
if (flag1==true && ((millis() - time) > 5000))
{ digitalWrite(7, HIGH);
  delay (1000);
  digitalWrite(7, LOW);
}
}
[code]

ora che ho risolto la parte iniziale ....
chiedo se nonstante funzioni tutto perfettamente
se è possibile semplificarlo in qualche modo (se necessario)...
ma dovrei implementare inserendo un altra condizione if... e cioè:
far si che si attivi relè anche nel caso che si verifichi la seguente condizione:
il valore [PCOMP] superi i 12200 per 1 secondo e scenda per 1/2 secondo continuamente per
10 secondiattivi.
ho pensato alla creazione di una media e nel caso il valore superi una certa soglia attivi relè.
in attesa vs. commenti grazie

Mi spieghi cosa ha a che vedere il codice per la MPU6050 con il problema del sensore barometrico e con quanto chiedevi prima ? Non ci sto capendo più molto ... ::slight_smile:

Guglielmo

e lo so ..... appena finito posto il progetto completo. Promesso.
cmq grazie di tutto...