Aiuto progetto 4 Sonde Temperatura e uscite di potenza.

ciao a tutti, premetto che sono nuovo a questo mondo e vorrei chiedervi un aiuto per la creazione di un piccolo progetto con base Arduino. La parte di programmazione non mi preoccupa, quello su cui ho dubbi è la parte elettronica e di schede necessarie. Ho la necessità di controllare 4 sonde di temperatura che dovranno essere poste a circa 10/15 metri dalla scheda Arduino. Ogni sonda mi dovrà fornira un dato preciso a 0,5°C ed in base a differenti valori di questo dato devo azionare 6 differenti uscite digitali di potenza. Il tutto dovrebbe inoltre fornirmi un allarmistica tramite GSM e un interfaccia Ethernet per poter leggere i dati di temperatura tramite protocollo SNMP.

Potete darmi qualche dritta da dove cominciare ? Ad esempio posso prendere una scheda Arduino ed aggiungere sia la NetShield che la GSM Shield ci sono complicazioni in merito ? Quali sonde di temperatura devo utilizzare ? Posso averne 4 differenziate ?

Grazie mille in anticipo a chiunque voglia dare una risposta.

Quali remperature devi misurarci ? … dipende anche da questo, il tipo di sonde da usare … :wink:

giusto, mi era sfuggito il range da misurare va da -10 a +40
Se fosse possibile avere anche la rilevazione dell’umidità con la stessa sonda sarebbe perfetto.

Per la temperatura e umidità puoi usare 4 DHT22, sono dei sensori one-wire, quindi oltre a 5V e GND devi collegare solo un pin dati: 4 sensori, 4 pin. (non sono water-proof) La Ethernet shield utilizza i pin dell'interfaccia SPI, sulla UNO sono 11, 12, 13 e il 10 per la selezione (più il 4 se vuoi usare la SD per datalogging). La GSM Shield ufficiale usa i pin 2, 3 e 7. Rimangono, a parte i pin 0 e 1 (per la seriale di debugging e la programmazione) insieme 5, 6, 8 e 9 che userai per i DHT, i 6 analogici/digitali che userai per le uscite. Direi che come pin sei a posto.

Dovresti controllare la compatibilità software. Ma non credo, ad occhio, che ci siano problemi.

se devi misurare la temperatura di un gas le DHT22 sono le ideali

PaoloP: Per la temperatura e umidità puoi usare 4 DHT22, sono dei sensori one-wire, quindi oltre a 5V e GND devi collegare solo un pin dati: 4 sensori, 4 pin. (non sono water-proof) La Ethernet shield utilizza i pin dell'interfaccia SPI, sulla UNO sono 11, 12, 13 e il 10 per la selezione (più il 4 se vuoi usare la SD per datalogging). La GSM Shield ufficiale usa i pin 2, 3 e 7. Rimangono, a parte i pin 0 e 1 (per la seriale di debugging e la programmazione) insieme 5, 6, 8 e 9 che userai per i DHT, i 6 analogici/digitali che userai per le uscite. Direi che come pin sei a posto.

Dovresti controllare la compatibilità software. Ma non credo, ad occhio, che ci siano problemi.

ciao,

qui a grandi linee trovi tutti gli shield di maggior interesse completi di pinout e relativi disegni, se usi sonde 1-Wire potresti anche utilizzare un solo pin per comunicare con un numero x di sonde (es. 4 temperature);

altre sonde di temperatura 1-Wire sono le Dallas DS18B20 waterproof che puoi interfacciare in modo molto semplice ad arduino, vedi qui per esempio, inoltre puoi utilizzare come uscite di potenza, dei moduli a relè su bus I2C tipo questo: http://www.byvac.com/bv3/index.php?route=product/product&product_id=82

essendo un bus, puoi interfacciare anche più di un modulo, ed esistono moduli a 4 ed a 8 relè :)

vedi di seguito i due schield sovrapposti ed i relativi pin utilizzati (es. http://shieldlist.org/sparkfun/cellular e http://shieldlist.org/arduino/ethernet-v5)

il bus I2C su arduinoUno/Ethernet si sviluppa sui pin A4 (SDA), A5 (SCL)

saluti kattivik76

Katt
le DS non hanno la misura della umidità, mentre le DHT non possono essere messe in comune perchè mi pare non abbiano indirizzo.
Usano una loro libreria che simula la 1-wire, ma non sono proprio delle 1-wire.

si si, è vero, ma se ha bisogno sonde di temperatura per esterno queste sono impermeabili

il DHT11/22 lo può collegare al bus 1-wire_simulato tramite un pin disponibile (testato già da me) senza alcun problema :slight_smile:

in questo sketch di esempio ho utilizzato:
n°1 RTC I2C
n°1 BMP085 (pressione) I2C
n°1 DHT11 (umidità+temperatura) I2C
n°1 display TFT I2C
n°1 DS18B20 (temperatura) 1-Wire

ho utilizzando i pin “2” - “7” - “A4” - “A5” :slight_smile:

cronotermostato_tft

#include "DHT11.h"
#include "RTClib.h"
#include <Wire.h>
#include <OneWire.h>
#include <Adafruit_BMP085.h>
#include <DallasTemperature.h>
#include <Flash.h>
#include <SMARTGPU_ATMEGA.h>     //include the SMARTGPU library!

// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
// EOC is not used, it signifies an end of conversion
// XCLR is a reset pin, also not used here

//create our object called LCD
SMARTGPU_ATMEGA lcd;            
 //create our object called RTC
RTC_Millis RTC;

dht11 DHT11;
#define DHT11PIN 2

#define ONE_WIRE_BUS              7
#define TEMPERATURE_PRECISION     12

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// arrays to hold device addresses
DeviceAddress bufAddr = { 0x28,0x12,0x6A,0x08,0x03,0x00,0x00,0x7F };

//DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP085 bmp;
float BMP085_Pressure = 0;
float BMP085_Temperature = 0;
float BMP085_Altitude = 0;
float DHT11_Humidity = 0;
float DHT11_Temperature = 0;
float DHT11_DewPoint = 0;
float DS_Temperature = 0;

int RTC_year = 0;
int RTC_month = 0;
int RTC_day = 0;
int RTC_hour = 0;
int RTC_minute = 0;
int RTC_second = 0;
int RTC_dayOfWeek = 0;

//Each time we use the touchscreen we must define a int array that stores the X and Y readed or touched coordinates.
int touch[2];
//Each time we use the touchicon we must define a char array that stores the name of the touched icon.
char icon[3];

void setup() {
  lcd.init();  //configure the serial and pinout of arduino board for SMARTGPU support
  lcd.start(); //initialize the SMARTGPU processor
  
  Serial.begin(9600);
  RTC.begin(DateTime(__DATE__, __TIME__));
  Setup_DS18x20();
  
  if (!bmp.begin()) {
    Serial.println("Could not find a valid BMP085 sensor, check wiring!");
    while (1) {}
  }  
  // Set a fast baud!, always that we use touch functions is recommended to use fast baud rates
  Serial.println(DHT11LIB_VERSION);
  lcd.baudChange(2000000);                 
  //spalsh screen
  lcd.imageSD(0,0,"splash");
  delay(5000);
}

void loop() {
  Serial.println();
  read_RTC();
  DS_Temperature = ReadDS18x20(bufAddr);
  read_BPM085_Sensor();
  read_DHT11_Sensor();
  
  Serial.print("DS_Temperature: ");
  Serial.println(DS_Temperature);
  //Serial.print("Temperature (oC): ");
  //Serial.println((float)DHT11.temperature, 2);
  //Serial.print("Dew Point (oC): ");
  //Serial.println(dewPoint(DHT11.temperature, DHT11.humidity));
  //Serial.print("Dew PointFast (oC): ");
  //Serial.println(dewPointFast(DHT11.temperature, DHT11.humidity));
  delay(1000);
}
void read_RTC(){
  char strDay[10];
  char strMonth[15];
  
  DateTime now = RTC.now();
  RTC_year = now.year();
  RTC_month = now.month();
  RTC_day = now.day();
  RTC_hour = now.hour();
  RTC_minute = now.minute();
  RTC_second = now.second();
  RTC_dayOfWeek = now.dayOfWeek();
  Serial.print(RTC_day);
  Serial.print('/');
  Serial.print(RTC_month);
  Serial.print('/');
  Serial.print(RTC_year);
  Serial.print(' ');
  Serial.print(RTC_hour);
  Serial.print(':');
  Serial.print(RTC_minute);
  Serial.print(':');
  Serial.print(RTC_second);
  Serial.println();
  //string(int x1, int y1, int x2, int y2, int colour, uint8_t font, uint8_t fill, char text[]);
  switch(RTC_month){
    case 1:
      sprintf(strMonth, "%s", "Gennaio");
    break;
    }
    Serial.println(strMonth);
  switch(RTC_dayOfWeek){
    case 1:
      sprintf(strDay, "%s", "Lunedi'", " %d", RTC_day, strMonth, RTC_year );      // convert data from long to char
    break;
    case 2:
      sprintf(strDay, "%s", "Martedi'");      // convert data from long to char
    break;
    case 3:
      sprintf(strDay, "%s", "Mercoledi'");      // convert data from long to char
    break;
    case 4:
      sprintf(strDay, "Giovedi' %d", RTC_day, " %s", strMonth, "%d", RTC_year );      // convert data from long to char
    break;
    case 5:
      sprintf(strDay, "%s", "Venerdi'");      // convert data from long to char
    break;
    case 6:
      sprintf(strDay, "%s", "Sabato");      // convert data from long to char
    break;
    case 7:
      sprintf(strDay, "%s", "Domenica");      // convert data from long to char
    break;
    }
    Serial.println(strDay);
    lcd.string(0,2,100,10,RED,3,0,strDay);
}


void read_BPM085_Sensor() {
  BMP085_Pressure = bmp.readPressure() / 100;
  BMP085_Temperature = bmp.readTemperature();
  BMP085_Altitude = bmp.readAltitude(101300);
  Serial.print("Temperature = ");
  Serial.print(BMP085_Temperature);
  Serial.println(" *C");
  
  Serial.print("Pressure = ");
  Serial.print(BMP085_Pressure);
  Serial.println(" mbar");
  
  Serial.print("Real altitude = ");
  Serial.print(BMP085_Altitude);
  Serial.println(" meters");
}

void read_DHT11_Sensor(){
  int chk = DHT11.read(DHT11PIN);

  Serial.print("Read sensor: ");
  switch (chk)
  {
    case DHTLIB_OK: 
                Serial.println("OK"); 
                break;
    case DHTLIB_ERROR_CHECKSUM: 
                Serial.println("Checksum error"); 
                break;
    case DHTLIB_ERROR_TIMEOUT: 
                Serial.println("Time out error"); 
                break;
    default: 
                Serial.println("Unknown error"); 
                break;
  }
  DHT11_Humidity = DHT11.humidity;
  DHT11_Temperature = DHT11.temperature;
  DHT11_DewPoint = dewPointFast(DHT11.temperature, DHT11.humidity);

  Serial.print("Humidity (%): ");
  Serial.println(DHT11_Humidity);
  Serial.print("Temperature (oC): ");
  Serial.println(DHT11_Temperature);
  //Serial.print("Dew Point (oC): ");
  //Serial.println(dewPoint(DHT11.temperature, DHT11.humidity));
  Serial.print("Dew PointFast (oC): ");
  Serial.println(DHT11_DewPoint);
}

//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
        return 1.8 * celsius + 32;
}

//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
        return celsius + 273.15;
}

// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
        double A0= 373.15/(273.15 + celsius);
        double SUM = -7.90298 * (A0-1);
        SUM += 5.02808 * log10(A0);
        SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
        SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM-3) * humidity;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558-T);
}

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
        double a = 17.271;
        double b = 237.7;
        double temp = (a * celsius) / (b + celsius) + log(humidity/100);
        double Td = (b * temp) / (a - temp);
        return Td;
}

DS18x20_Temperature

void Setup_DS18x20(void)
{
  // Start up the library
  sensors.begin();
  sensors.setResolution(bufAddr, TEMPERATURE_PRECISION);
}

// function read 1ware dallas temperature DS18B20
float ReadDS18x20(byte* MyAddress){
  // send read request
  oneWire.reset();
  sensors.requestTemperatures();
  //float sensordata = sensors.getTempC(MyAddress);
  return sensors.getTempC(MyAddress); //sensordata;
  }
  
// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}
// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}

saluti
kattivik76