Signalduino mit selbstgebauten DHT11 Sensor

Begonnen von Groej, 09 August 2017, 12:55:21

Vorheriges Thema - Nächstes Thema

Groej

Hallo an alle,

ich hoffe das ist der richtiger Bereich vom Forum dafür. Ich hab gerade dies hier im Netz gefunden: http://labalec.fr/erwan/?p=1534.

Das ist ein Anttiny85 mit einen DHT11 und einen RF433MHz Sender. Jetzt kommt der Clou. Das ganze soll mit dem Oregon V2.1 Protokoll laufen.
Meint Ihr das würde der Signalduino erkennen?

/*
* connectingStuff, Oregon Scientific v2.1 Emitter
* http://connectingstuff.net/blog/encodage-protocoles-oregon-scientific-sur-arduino/
*
* Copyright (C) 2013 olivier.lebrun@gmail.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/



#include <avr/sleep.h>
#include <avr/wdt.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

volatile boolean f_wdt = 1;

#include <dht11.h>
#define DHT11PIN PB1
dht11 DHT11;


#include <SoftwareSerial.h>
#define SERIAL_RX PB3 //pin 2 //INPUT
#define SERIAL_TX PB4 //pin 3 //OUTPUT
SoftwareSerial TinySerial(SERIAL_RX, SERIAL_TX); // RX, TX


//#define THN132N

const byte TX_PIN = 0;


const unsigned long TIME = 512;
const unsigned long TWOTIME = TIME*2;

#define SEND_HIGH() digitalWrite(TX_PIN, HIGH)
#define SEND_LOW() digitalWrite(TX_PIN, LOW)

// Buffer for Oregon message
#ifdef THN132N
  byte OregonMessageBuffer[8];
#else
  byte OregonMessageBuffer[9];
#endif

/**
* \brief    Send logical "0" over RF
* \details  azero bit be represented by an off-to-on transition
* \         of the RF signal at the middle of a clock period.
* \         Remenber, the Oregon v2.1 protocol add an inverted bit first
*/
inline void sendZero(void)
{
  SEND_HIGH();
  delayMicroseconds(TIME);
  SEND_LOW();
  delayMicroseconds(TWOTIME);
  SEND_HIGH();
  delayMicroseconds(TIME);
}

/**
* \brief    Send logical "1" over RF
* \details  a one bit be represented by an on-to-off transition
* \         of the RF signal at the middle of a clock period.
* \         Remenber, the Oregon v2.1 protocol add an inverted bit first
*/
inline void sendOne(void)
{
   SEND_LOW();
   delayMicroseconds(TIME);
   SEND_HIGH();
   delayMicroseconds(TWOTIME);
   SEND_LOW();
   delayMicroseconds(TIME);
}

/**
* Send a bits quarter (4 bits = MSB from 8 bits value) over RF
*
* @param data Source data to process and sent
*/

/**
* \brief    Send a bits quarter (4 bits = MSB from 8 bits value) over RF
* \param    data   Data to send
*/
inline void sendQuarterMSB(const byte data)
{
  (bitRead(data, 4)) ? sendOne() : sendZero();
  (bitRead(data, 5)) ? sendOne() : sendZero();
  (bitRead(data, 6)) ? sendOne() : sendZero();
  (bitRead(data, 7)) ? sendOne() : sendZero();
}

/**
* \brief    Send a bits quarter (4 bits = LSB from 8 bits value) over RF
* \param    data   Data to send
*/
inline void sendQuarterLSB(const byte data)
{
  (bitRead(data, 0)) ? sendOne() : sendZero();
  (bitRead(data, 1)) ? sendOne() : sendZero();
  (bitRead(data, 2)) ? sendOne() : sendZero();
  (bitRead(data, 3)) ? sendOne() : sendZero();
}

/******************************************************************/
/******************************************************************/
/******************************************************************/

/**
* \brief    Send a buffer over RF
* \param    data   Data to send
* \param    size   size of data to send
*/
void sendData(byte *data, byte size)
{
  for(byte i = 0; i < size; ++i)
  {
    sendQuarterLSB(data[i]);
    sendQuarterMSB(data[i]);
  }
}

/**
* \brief    Send an Oregon message
* \param    data   The Oregon message
*/
void sendOregon(byte *data, byte size)
{
    sendPreamble();
    //sendSync();
    sendData(data, size);
    sendPostamble();
}

/**
* \brief    Send preamble
* \details  The preamble consists of 16 "1" bits
*/
inline void sendPreamble(void)
{
  byte PREAMBLE[]={0xFF,0xFF};
  sendData(PREAMBLE, 2);
}

/**
* \brief    Send postamble
* \details  The postamble consists of 8 "0" bits
*/
inline void sendPostamble(void)
{
#ifdef THN132N
  sendQuarterLSB(0x00);
#else
  byte POSTAMBLE[]={0x00};
  sendData(POSTAMBLE, 1); 
#endif
}

/**
* \brief    Send sync nibble
* \details  The sync is 0xA. It is not use in this version since the sync nibble
* \         is include in the Oregon message to send.
*/
inline void sendSync(void)
{
  sendQuarterLSB(0xA);
}

/******************************************************************/
/******************************************************************/
/******************************************************************/

/**
* \brief    Set the sensor type
* \param    data       Oregon message
* \param    type       Sensor type
*/
inline void setType(byte *data, byte* type)
{
  data[0] = type[0];
  data[1] = type[1];
}

/**
* \brief    Set the sensor channel
* \param    data       Oregon message
* \param    channel    Sensor channel (0x10, 0x20, 0x30)
*/
inline void setChannel(byte *data, byte channel)
{
    data[2] = channel;
}

/**
* \brief    Set the sensor ID
* \param    data       Oregon message
* \param    ID         Sensor unique ID
*/
inline void setId(byte *data, byte ID)
{
  data[3] = ID;
}

/**
* \brief    Set the sensor battery level
* \param    data       Oregon message
* \param    level      Battery level (0 = low, 1 = high)
*/
void setBatteryLevel(byte *data, byte level)
{
  if(!level) data[4] = 0x0C;
  else data[4] = 0x00;
}

/**
* \brief    Set the sensor temperature
* \param    data       Oregon message
* \param    temp       the temperature
*/
void setTemperature(byte *data, float temp)
{
  // Set temperature sign
  if(temp < 0)
  {
    data[6] = 0x08;
    temp *= -1; 
  }
  else
  {
    data[6] = 0x00;
  }

  // Determine decimal and float part
  int tempInt = (int)temp;
  int td = (int)(tempInt / 10);
  int tf = (int)round((float)((float)tempInt/10 - (float)td) * 10);

  int tempFloat =  (int)round((float)(temp - (float)tempInt) * 10);

  // Set temperature decimal part
  data[5] = (td << 4);
  data[5] |= tf;

  // Set temperature float part
  data[4] |= (tempFloat << 4);
}

/**
* \brief    Set the sensor humidity
* \param    data       Oregon message
* \param    hum        the humidity
*/
void setHumidity(byte* data, byte hum)
{
    data[7] = (hum/10);
    data[6] |= (hum - data[7]*10) << 4;
}

/**
* \brief    Sum data for checksum
* \param    count      number of bit to sum
* \param    data       Oregon message
*/
int Sum(byte count, const byte* data)
{
  int s = 0;

  for(byte i = 0; i<count;i++)
  {
    s += (data[i]&0xF0) >> 4;
    s += (data[i]&0xF);
  }

  if(int(count) != count)
    s += (data[count]&0xF0) >> 4;

  return s;
}

/**
* \brief    Calculate checksum
* \param    data       Oregon message
*/
void calculateAndSetChecksum(byte* data)
{
#ifdef THN132N
    int s = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff);

    data[6] |=  (s&0x0F) << 4;     data[7] =  (s&0xF0) >> 4;
#else
    data[8] = ((Sum(8, data) - 0xa) & 0xFF);
#endif
}



/******************************************************************/

void setup()
{
  setup_watchdog(9);
  //pinMode(PB3, OUTPUT);
  //digitalWrite(PB3,HIGH);delay(500);
  //digitalWrite(PB3,LOW);delay(500);
  //digitalWrite(PB3,HIGH);
  pinMode(TX_PIN, OUTPUT);
 

pinMode(PB4, OUTPUT); //tx
  TinySerial.begin(9600);
  TinySerial.println("\n[Oregon V2.1 encoder]");

  SEND_LOW();

 
#ifdef THN132N 
  // Create the Oregon message for a temperature only sensor (TNHN132N)
  byte ID[] = {0xEA,0x4C};
#else
  // Create the Oregon message for a temperature/humidity sensor (THGR2228N)
  byte ID[] = {0x1A,0x2D};
#endif 

  setType(OregonMessageBuffer, ID);
  setChannel(OregonMessageBuffer, 0x20);
  setId(OregonMessageBuffer, 0xEE);
}


// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {
  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF

  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();

  sleep_mode();                        // System sleeps here

  sleep_disable();                     // System continues execution here when watchdog timed out
  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
}

// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;

  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCR = bb;
  WDTCR |= _BV(WDIE);
}
 
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}


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

   switch (chk)
  {
    case DHTLIB_OK:
      TinySerial.println("OK");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      TinySerial.println("Checksum error");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      TinySerial.println("Time out error");
      break;
    default:
      TinySerial.println("Unknown error");
      break;
  }
   
  TinySerial.print("Temperature : ");TinySerial.print(DHT11.temperature);TinySerial.write(176); // caractère °
  TinySerial.write('C'); TinySerial.println();
  TinySerial.print("Humidity : ");TinySerial.print(DHT11.humidity);
  TinySerial.write('%'); TinySerial.println();

  // (ie: 1wire DS18B20 for température, ...)
  setBatteryLevel(OregonMessageBuffer, 0); // 0 : low, 1 : high
  setTemperature(OregonMessageBuffer, DHT11.temperature);

#ifndef THN132N
  // Set Humidity
  setHumidity(OregonMessageBuffer, DHT11.humidity);
#endif 

  // Calculate the checksum
  calculateAndSetChecksum(OregonMessageBuffer);

  // Show the Oregon Message
  for (byte i = 0; i < sizeof(OregonMessageBuffer); ++i)   {     
    //TinySerial.print(OregonMessageBuffer[i] >> 4, HEX);
    //TinySerial.print(OregonMessageBuffer[i] & 0x0F, HEX);
  }

  // Send the Message over RF
  sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));
  // Send a "pause"
  SEND_LOW();
  delayMicroseconds(TWOTIME*8);
  // Send a copie of the first message. The v2.1 protocol send the
  // message two time
  sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));

  // Wait for 30 seconds before send a new message
  SEND_LOW();
  //

  //9 secs * 6 = 54 secs
  system_sleep();
  system_sleep();
  system_sleep();
  system_sleep();
  system_sleep();
  system_sleep();
  //
  //delay(30000);
 
}


Ich weiß nur noch nicht wo ich in dem Sketch eine ID einstellen kann oder so damit man die Sender unterscheiden kann. Ich würde das auch gerne gegen einen DHT22 tauschen. Da müßte der Sketch doch nur umgeschrieben werden bzw. die andere Libary geladen werden oder irre ich mich da jetzt. Bin auf den Gebiet Arduino leider noch etwas unbeleckt.

Danke für eure Meinung bzw. Tipps.

Gruß

Jörg
FHEM - RaspPi2 - KNXD - KNX - CUL 868 - FS20 - HMS - WH3080 - Signalduino 433 MHz - Telegram - Anel Elektronik IP Steckdosen - BME280

gloob

#1
Hier kannst du die ID setzen:

/**
* \brief    Set the sensor ID
* \param    data       Oregon message
* \param    ID         Sensor unique ID
*/
inline void setId(byte *data, byte ID)
{
  data[3] = ID;
}


wird im "Setup" aufgerufen:

setId(OregonMessageBuffer, 0xEE);

Und laut dem hier:

Zitathttps://forum.fhem.de/index.php?topic=60170.0

werden Oregon Sensoren mit V2 und V3 vom Signalduino unterstützt.

Und hier findest du eine Bibliothek für den DHT22:

Zitathttp://forum.arduino.cc/index.php?topic=174340.0
Raspberry Pi 3 | miniCUL 433MHz | nanoCUL 868 MHz | nanoCUL 433 MHz | MySensors WLAN Gateway | LaCrosse WLAN Gateway | SignalESP 433 MHz | SignalESP 868 MHz | HM-MOD-UART WLAN Gateway | IR - 360 Grad WLAN Gateway

RaspiLED

Ja supi,
Mach mal fertig und poste hier Deinen DHT22 Code und die Pinbelegung. Wer hat gute Ideen für Gehäuse?
Was sind die Kosten inkl. aller Teile aus Eurer Erfahrung?
Gruß Arnd


Raspi2 mit FHEM, CUL, Signalduino, MySensors, HomeBridge, Presence, Bravia, ...
Raspberry Pi mit FHEM, CUL, Signalduino, MySensors, HomeBridge, Presence, WifiLight2, Bravia, ...

Groej

Hallo,

das der Signalduino das auf dem Papier kann hatte ich damals schon gesehen darum fand ich das was ich gefunden habe ja so Genial. Frage ist nur ob er es dann auch erkennt :).
Ich hab gerade versucht den DHT22 einzubinden aber schaff es nicht. Kommt immer ein Fehler beim kompilieren aber wie gesagt ist das absolutes Neuland für mich. Kann da aber erst nach meinen Urlaub weiter machen.
Zu den Kosten kann ich nichts sagen aber denke wird nicht viel sein.

Gruß
FHEM - RaspPi2 - KNXD - KNX - CUL 868 - FS20 - HMS - WH3080 - Signalduino 433 MHz - Telegram - Anel Elektronik IP Steckdosen - BME280

Groej

#4
Hallo,

hab gerade das im FHEM Forum gefunden: https://forum.fhem.de/index.php?topic=52755.15

Seite 2 Antwort 19 und 21

Eigentlich das gleiche aber schon mit DHT22 aber mit LaCrosse was der Signalduino ja auch kann.

Gruß
FHEM - RaspPi2 - KNXD - KNX - CUL 868 - FS20 - HMS - WH3080 - Signalduino 433 MHz - Telegram - Anel Elektronik IP Steckdosen - BME280