Selbstbau Funkthermometer 433Mhz

Begonnen von matlen67, 28 April 2016, 09:59:57

Vorheriges Thema - Nächstes Thema

juergs

#315
Hallo Bender78,
Das liegt eher an der Auflösung des Timers, da dessen Überläufe gezählt werden müssen!

Der Nano hat noch Spannungsregler auf dem Board.
Deren Leerlauf-Stromverbrauch ist sehr hoch...
Dein angegebener Stromverbrauch erscheint mir ok...

Ich gehe davon aus, dass Du noch den Code von Programm von Matthias Kleine benutzt?

Wie sieht es aus, wenn Du diesen hier aus diesem Thread mal flashst?

Jürgen

Bender78

Zitat von: juergs am 04 Dezember 2018, 15:37:10
Hallo Bender78,
Das liegt eher an der Auflösung des Timers, da dessen Überläufe gezählt werden müssen!

Ich gehe davon aus, dass Du noch den Code von Programm von Matthias Kleine benutzt?

Wie sieht es aus, wenn Du diesen hier aus diesem Thread mal flashst?

Jürgen

Hallo Jürgen,
danke für deine Antwort. Leider komme ich erst jetzt dazu weitere Fragen zu stellen :D ...Vorweihnachtsstress...
Kannst du mir vielleicht genauer erläutern was es mit der Auflösung des Timers zu tun hat? Ich würde es gerne verstehen wollen, bin aber in der Thematik absoluter Anfänger.

Ja ich verwende den Code von Matthias Kleine. Es hat mich so gefreut, das ich es auf anhieb geschafft habe und hab daher keinen weiteren Code mehr getestet. Im Grunde reicht es mir ja auch, dass nur alle paar Minuten ein Wert bei FHEM ankommt.  Aber natürlich ist es ja nicht Sinn und Zweck, wenn der kleine Kerl alle 8 Sek aus seinem schlaf geholt wird und dann nichts empfangen wird.

juergs

#317
Die Antwort ist eigentlich ganz einfach:
Du hattest es eigentlich schon selbst erwähnt:
Zitat... dass nur alle paar Minuten.

Vereinfachtes Rechenbeispiel: 1 Minute = 60 Sekunden = 60 *  (1/8 Millionen Takte = geschätzte Taktrate ATtiny ggf. abzüglich Prescaler-Einstellungen)

Näheres:
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR
https://www.mikrocontroller.net/articles/AVR-Tutorial:_Power_Management#Sleep_Modi

Zitat... Das alleine wäre noch nicht allzu nützlich, wenn nicht dieses Hardwareregister bei bestimmten Zählerständen einen Interrupt auslösen könnte.
Ein solches Ereignis ist der Overflow (Überlauf): Da die Bitbreite des Registers beschränkt ist, kommt es natürlich auch vor, dass der Zähler so hoch zählt, dass der nächste Zählerstand mit dieser Bitbreite nicht mehr darstellbar ist und der Zähler wieder auf 0 zurückgesetzt wird.

Deshalb muss der Controller früher aufwachen und prüfen, ob die Anzahl der Überläufe den gewünschten Minuten-Zählerwert erreicht  hat.
Wenn nicht geht er wieder einen Timer-Overflow-Zyklus schlafen ...

Sagen wir mal so: das muss System-bedingt so sein ;-)




Bender78

Zitat von: juergs am 08 Dezember 2018, 12:02:11

Deshalb muss der Controller früher aufwachen und prüfen, ob die Anzahl der Überläufe den gewünschten Minuten-Zählerwert erreicht  hat.
Wenn nicht geht er wieder einen Timer-Overflow-Zyklus schlafen ...

Sagen wir mal so: das muss System-bedingt so sein ;-)

Dank Jürgen.  OK. Aber wenn ich den Sleep deaktiviere habe ich ja das selbe problem, dass er nicht regelmäßig sendet. Ich dachte ja zunächst auch das es daran liegt. Aber das habe ich ja dann auch getestet ohne Sleep des Attiny

Bender78

#319
So.. nun habe ich alles noch einmal auf das Wesentliche reduziert.
Es bleibt dabei. Alle 20sek. - 5 Minuten kommt ein Wert an. Komplett unterschiedlich. Habe eine LED ziwschen SendePin und GND gesteckt. Diese pollt regelmäsig alle 5sek.
Würde nur gerne verstehen, warum das so ist..

#include <TX3.h>
///#include <avr/sleep.h>
///#include <avr/wdt.h>
#include "DHT.h"
#define PIN_SEND PB3
#define SENSORID 101   
#define DHT22PIN PB4

TX3 tx3(PIN_SEND, SENSORID);
//DHT dht22(DHT22PIN, DHT22);


void setup() {

//dht22.begin();


}


void loop() {

//float humidity = dht22.readHumidity();
//float temp = dht22.readTemperature();
   tx3.sendHumidity(55.5);
   tx3.sendTemperature(23.3);
   delay(5000);

}

juergs

#320
... schaue doch mal da rein: https://github.com/juergs/_ATtiny85_DHT22_BMP180_433
bzw. packe mal den gesamten Code zusammen und poste diesen ...

Bei dem delay(500) scheint das Timing es ja korrekt zu funktionieren ...
Könntest Du auch mal negative Temperaturen testen?


Jürgen

Bender78

Hallo Jürgen,

vielen Dank für deine Hilfe.  Ich denke ich werde morgen mal dein Programm testen. Bin gerade ein wenig enttäuscht von dem Dallas 18b20 mit dem habe ich alles getestet.  Der lag bei Zimmertemperatur nur 0,2 Grad unter meinem Temperaturmessgerät. Nun aber unser Tiefkühle komplett daneben. Dort sind ca -20°C und angezeigt hat er -49°C 🤔

hbulf

Hallo Jürgen,

gibt es schon neue Erkenntnisse warum das mit den Minus Temperaturen nicht funktioniert?

VG

Ulf


juergs

#324
Hallo hbulf,

sorry, "Zeitproblem" + musste erst wieder Testsystem aufbauen ...

Ich habe den Code hier für den ATtiny85_1820_433 nochmal nur für den 18B20 zusammengestellt.
Die ID im Code lautet 80. Die von anderen vorgeschlagenen Timings habe ich mal mit im Code angegeben.

Heute könnte es auch mit den negativen Temperaturen klappen, deshalb habe ich den Sensor mal Außen positioniert.  ;)


juergs

#325

2018-12-15_16:33:06 CUL_TX_80 T: 21.4
2018-12-15_16:33:06 CUL_TX_80 temperature: 21.4
2018-12-15_16:36:20 CUL_TX_80 T: 21.4
2018-12-15_16:36:20 CUL_TX_80 temperature: 21.4
2018-12-15_16:39:34 CUL_TX_80 T: 22.0
2018-12-15_16:39:34 CUL_TX_80 temperature: 22.0
2018-12-15_16:42:48 CUL_TX_80 T: 21.6
2018-12-15_16:42:48 CUL_TX_80 temperature: 21.6
2018-12-15_16:46:03 CUL_TX_80 T: 21.
2018-12-15_16:46:03 CUL_TX_80 temperature: 21.6
2018-12-15_16:49:17 CUL_TX_80 T: 21.5
2018-12-15_16:49:17 CUL_TX_80 temperature: 21.5
2018-12-15_16:52:31 CUL_TX_80 T: 21.5
2018-12-15_16:52:31 CUL_TX_80 temperature: 21.5
2018-12-15_16:55:45 CUL_TX_80 T: 21.5
2018-12-15_16:55:45 CUL_TX_80 temperature: 21.5
2018-12-15_16:58:59 CUL_TX_80 T: 21.5
2018-12-15_16:58:59 CUL_TX_80 temperature: 21.5
2018-12-15_17:02:14 CUL_TX_80 T: 21.4
2018-12-15_17:02:14 CUL_TX_80 temperature: 21.4
2018-12-15_17:05:28 CUL_TX_80 T: 21.4
2018-12-15_17:05:28 CUL_TX_80 temperature: 21.4
2018-12-15_17:10:02 CUL_TX_80 T: 11.1
2018-12-15_17:10:02 CUL_TX_80 temperature: 11.1
2018-12-15_17:13:15 CUL_TX_80 T: 4.1
2018-12-15_17:13:15 CUL_TX_80 temperature: 4.1
2018-12-15_17:16:28 CUL_TX_80 T: 2.8
2018-12-15_17:16:28 CUL_TX_80 temperature: 2.8
2018-12-15_17:19:41 CUL_TX_80 T: 1.5
2018-12-15_17:19:41 CUL_TX_80 temperature: 1.5
2018-12-15_17:26:06 CUL_TX_80 T: 1.4
2018-12-15_17:26:06 CUL_TX_80 temperature: 1.4
2018-12-15_17:29:18 CUL_TX_80 T: 1.1
2018-12-15_17:29:18 CUL_TX_80 temperature: 1.1
2018-12-15_17:32:31 CUL_TX_80 T: 0.6
2018-12-15_17:32:31 CUL_TX_80 temperature: 0.6
2018-12-15_17:38:56 CUL_TX_80 T: 0.5
2018-12-15_17:38:56 CUL_TX_80 temperature: 0.5
2018-12-15_17:45:21 CUL_TX_80 T: 0.6
2018-12-15_17:45:21 CUL_TX_80 temperature: 0.6
2018-12-15_17:48:34 CUL_TX_80 T: 0.7
2018-12-15_17:48:34 CUL_TX_80 temperature: 0.7
2018-12-15_17:54:59 CUL_TX_80 T: 1.3
2018-12-15_17:54:59 CUL_TX_80 temperature: 1.3
2018-12-15_17:58:11 CUL_TX_80 T: 0.7
2018-12-15_17:58:11 CUL_TX_80 temperature: 0.7
2018-12-15_18:01:24 CUL_TX_80 T: 0.5
2018-12-15_18:01:24 CUL_TX_80 temperature: 0.5
2018-12-15_18:04:36 CUL_TX_80 T: 1.4
2018-12-15_18:04:36 CUL_TX_80 temperature: 1.4
2018-12-15_18:11:02 CUL_TX_80 T: 0.6
2018-12-15_18:11:02 CUL_TX_80 temperature: 0.6
2018-12-15_18:17:27 CUL_TX_80 T: 0.9
2018-12-15_18:17:27 CUL_TX_80 temperature: 0.9
2018-12-15_18:20:39 CUL_TX_80 T: 0.7
2018-12-15_18:20:39 CUL_TX_80 temperature: 0.7
2018-12-15_18:23:52 CUL2018-12-16_04:27:06 CUL_TX_80 temperature: 0.3
2018-12-16_04:30:19 CUL_TX_80 T: 0.0
2018-12-16_04:30:19 CUL_TX_80 temperature: 0.0
2018-12-16_04:33:31 CUL_TX_80 T: 0.0
2018-12-16_04:33:31 CUL_TX_80 temperature: 0.0
2018-12-16_04:36:44 CUL_TX_80 T: 0.0
2018-12-16_04:36:44 CUL_TX_80 temperature: 0.0
2018-12-16_04:39:56 CUL_TX_80 T: 0.0
2018-12-16_04:39:56 CUL_TX_80 temperature: 0.0
2018-12-16_04:43:09 CUL_TX_80 T: 0.0
2018-12-16_04:43:09 CUL_TX_80 temperature: 0.0
2018-12-16_04:46:21 CUL_TX_80 T: 0.9
2018-12-16_04:46:21 CUL_TX_80 temperature: 0.9
2018-12-16_04:49:34 CUL_TX_80 T: 0.0
2018-12-16_04:49:34 CUL_TX_80 temperature: 0.0
2018-12-16_04:55:58 CUL_TX_80 T: 0.0
2018-12-16_04:55:58 CUL_TX_80 temperature: 0.0
2018-12-16_05:12:01 CUL_TX_80 T: 0.0
2018-12-16_05:12:01 CUL_TX_80 temperature: 0.0
2018-12-16_05:15:13 CUL_TX_80 T: -45.0
2018-12-16_05:15:13 CUL_TX_80 temperature: -45.0
2018-12-16_05:44:05 CUL_TX_80 T: -45.0
2018-12-16_05:44:05 CUL_TX_80 temperature: -45.0
2018-12-16_05:47:17 CUL_TX_80 T: -45.0
2018-12-16_05:47:17 CUL_TX_80 temperature: -45.0
2018-12-16_05:50:30 CUL_TX_80 T: -45.0
2018-12-16_05:50:30 CUL_TX_80 temperature: -45.0
2018-12-16_05:53:42 CUL_TX_80 T: -45.0


Dann müssen wir die negativen Temperaturen noch Mal genauer anschauen.
Ach ja, die Schaltung wurde eingeschneit und muss erst Mal trocknen  ;D

juergs

#326
Zum Ausprobieren:

https://www.tutorialspoint.com/online_c_compiler.php

In SendTemperature werden 50 °C zu den Zehner-Stellen der gemessenen Temperatur  hinzugefügt!


#include <stdio.h>

#define TX3_MODELID  0x0A
#define sensorId 110


void sendNibbles(int type, int tens, int ones, int tenths);
void sendNibble(int i);
void sendTemperature(float t);
void O();
void I();

int main()
{
    float t = -10.5;
   
    printf("Hello, World. Testing temperatures below zero!\n");
   
    sendTemperature(t);
   
    printf("\n");
   
    printf("Float: %2.1f\n",t);

    int tens = ((int)t / 10) + 5;
    int ones= ((int)t % 10);
    int tenths = ((int)t * 10) % 10;
    printf("Tens: %d  ones: %d  tenths: %d\n",tens,ones,tenths);
   
    return 0;
}

void sendTemperature(float t)
{
  sendNibbles(
    0,
    ((int)t / 10) + 5,
    ((int)t % 10),
    ((int)t * 10) % 10
  );
}
void sendNibbles(int type, int tens, int ones, int tenths)
{
  int idr, checksum, parity;
  int nibble1, nibble2, nibble3, nibble4, nibble5, nibble6, nibble7, nibble8, nibble9, nibble10;

  // left  nibble of Model
  nibble1 = TX3_MODELID / 0x10;

  // right  nibble of Model
  nibble2 = TX3_MODELID & 0xF;

  nibble3 = type;

  // Nibble 4 is the left part of the Id
  // 1101 111?
  // 0110 1111
  nibble4 = sensorId / 0x08;

  nibble6 = tens;
  nibble7 = ones;
  nibble8 = tenths;

  nibble9 = tens;
  nibble10 = ones;

  // For Parity we need the last 3 bits of the Sensor ID
  idr = sensorId & 0x7;

  // Parity bit makes even parity for sum
  parity = (nibble4 + idr + nibble6 + nibble7 + nibble8 + nibble9 + nibble10) & 0x1;

  // nibble 5 is last 3 digits of Sensor and parity bit
  nibble5 = ((idr * 0x2) + parity) & 0xF;

  // Checksum nibble of all nibbles
  checksum = (nibble1 + nibble2 + nibble3 + nibble4 + nibble5 + nibble6 + nibble7 + nibble8 + nibble9 + nibble10) & 0xF;

  for (int r = 0; r < 1; r++) {
    //if(r > 0) delay(20);
    sendNibble(nibble1);
    sendNibble(nibble2);
    sendNibble(nibble3);
    sendNibble(nibble4);
    sendNibble(nibble5);
    sendNibble(nibble6);
    sendNibble(nibble7);
    sendNibble(nibble8);
    sendNibble(nibble9);
    sendNibble(nibble10);
    sendNibble(checksum);
  }
}

void sendNibble(int i)
{
  if (i & 8) I(); else O();
  if (i & 4) I(); else O();
  if (i & 2) I(); else O();
  if (i & 1) I(); else O();
}
void O()
{
  // sends zero
  printf("0");
}

void I()
{
  printf("1");
}



Zitat
sh-4.4$ gcc -o main *.c                                                                                                                                                                     
sh-4.4$ main                                                                                                                                                                                 
Hello, World. Testing temperatures below zero!                                                                                                                                               
00001010000011011101010000000000010000001100                                                                                                                                                 
Float: -10.5                                                                                                                                                                                 
Tens: 4  ones: 0  tenths: 0   


1        10        20        30        40  44
12345678901234567890123456789012345678901234567890
00001010000011011101010000000000010000001100


http://www.f6fbb.org/domo/sensors/tx3_th.php
https://github.com/guillier/433mhz_receiver/blob/master/tx_433mhz_digispark.ino

juergs

#327
Hier das Problem (Beispiel: -12.5 °C):

Hello, World. Testing temperatures below zero!                                                                                                                                               
00001010000011011101010011100000010011101000                                                                                                                                                 
Float: -12.5                                                                                                                                                                                 
Tens: 4  ones: -2  tenths: 0   


und SendNibbles erwartet positive Zahlen !



void TX3::sendTemperature(float t)
{
  int tens = ((int)t / 10) + 5;  //with + 50 degrees offset
  int ones= ((int)t % 10);
  int tenths = ((int)t * 10) % 10;

  //--- Erster Workaround: negatives hier verbieten
  if (ones < 0) ones = abs(ones);
  if (tenths < 0) tenths = abs(tenths);
 
  sendNibbles(
    TX3_COM_TEMP,
    tens,  //+ 50 degrees offset
    ones,
    tenths
  );
}


-12.5 °C liefert fhem:

state  T: -8.0 2018-12-16 15:09:48
temperature -8.0 2018-12-16 15:09:48


Aber:
Hello, World. Testing temperatures below zero!                                                                                                                                               
00001010000011011101010000100000010000100000                                                                                                                                                 
Float: -12.5                                                                                                                                                                                 
Tens: 4  ones: -2  tenths: 0                                                                                                                                                                 
Tens: 4  einer: 2  dezimale: 0   


50 -40 + 2  = -8 °C

Stimmt zwar in der fhem, aber kann das TX3 Protokoll negative Einer-Stellen?.
Also müssen wir das anders angehen...


juergs

#328
Ok, hier der Trick für negative Temperaturen:

=> negative Temperaturen müssen aufbereitet werden (Offset von +50 °C, werden im Protokoll bzw. fhem weggerechnet!).


void TX3::sendTemperature(float t)
{
  int tens, ones, tenths ;
  if (t >= 0)
  {
    tens = ((int)t / 10) + 5;  //with + 50 degrees offset
    ones= ((int)t % 10);
    tenths = ((int)t * 10) % 10;
  }
  else
  {
      //-- Beispiel:  50 + (- 12.5) = 37,5
      t = 50 + t;
      tens = ((int)t / 10);  //with + 50 degrees offset
      ones= ((int)t % 10);
      tenths = ((int)t * 10) % 10;       
  }     
  sendNibbles(
    TX3_COM_TEMP,
    tens,  //+ 50 degrees offset
    ones,
    tenths
  );
}


Zum nachprüfen:


#include <stdio.h>
#include <stdlib.h>

#define TX3_MODELID  0x0A
#define sensorId 110


void sendNibbles(int type, int tens, int ones, int tenths);
void sendNibble(int i);
void sendTemperature(float t);
void O();
void I();

int main()
{
    int tens, ones, tenths, einer , zehner, dezimale ;
    float t = -12.5;
   
    printf("Hello, World. Testing temperatures below zero!\n");
   
    sendTemperature(t);
   
    printf("\n");
    printf("Float: %2.1f\n",t);

    if (t> 0)
    {
        tens = ((int)t / 10) + 5;
        ones = ((int)t % 10);
        tenths = ((int)t * 10) % 10;
        printf("Tens: %d  ones: %d  tenths: %d\n",tens, ones, tenths);
    }
    else
    {
        t = 50 + t;
        printf("Float: %2.1f\n",t);
        tens = ((int)t / 10);
        ones = ((int)t % 10);
        tenths = ((int)t * 10) % 10;           
        printf("Zehner: %d  Einer: %d  Dezimale: %d\n",tens, ones , tenths );
    }
    return 0;
}

void sendTemperature(float t)
{
  sendNibbles(
    0,
    ((int)t / 10) + 5,
    abs(((int)t % 10)),
    abs(((int)t * 10) % 10)
  );
}
void sendNibbles(int type, int tens, int ones, int tenths)
{
  int idr, checksum, parity;
  int nibble1, nibble2, nibble3, nibble4, nibble5, nibble6, nibble7, nibble8, nibble9, nibble10;

  // left  nibble of Model
  nibble1 = TX3_MODELID / 0x10;

  // right  nibble of Model
  nibble2 = TX3_MODELID & 0xF;

  nibble3 = type;

  // Nibble 4 is the left part of the Id
  // 1101 111?
  // 0110 1111
  nibble4 = sensorId / 0x08;

  nibble6 = tens;
  nibble7 = ones;
  nibble8 = tenths;

  nibble9 = tens;
  nibble10 = ones;

  // For Parity we need the last 3 bits of the Sensor ID
  idr = sensorId & 0x7;

  // Parity bit makes even parity for sum
  parity = (nibble4 + idr + nibble6 + nibble7 + nibble8 + nibble9 + nibble10) & 0x1;

  // nibble 5 is last 3 digits of Sensor and parity bit
  nibble5 = ((idr * 0x2) + parity) & 0xF;

  // Checksum nibble of all nibbles
  checksum = (nibble1 + nibble2 + nibble3 + nibble4 + nibble5 + nibble6 + nibble7 + nibble8 + nibble9 + nibble10) & 0xF;

  for (int r = 0; r < 1; r++) {
    //if(r > 0) delay(20);
    sendNibble(nibble1);
    sendNibble(nibble2);
    sendNibble(nibble3);
    sendNibble(nibble4);
    sendNibble(nibble5);
    sendNibble(nibble6);
    sendNibble(nibble7);
    sendNibble(nibble8);
    sendNibble(nibble9);
    sendNibble(nibble10);
    sendNibble(checksum);
  }
}

void sendNibble(int i)
{
  if (i & 8) I(); else O();
  if (i & 4) I(); else O();
  if (i & 2) I(); else O();
  if (i & 1) I(); else O();
}
void O()
{
  // sends zero
  printf("0");
}

void I()
{
  printf("1");
}


Fazit:
Immer nur Copy&Paste .... werden auch Fehler mitkopiert  ;D :D ;)
Ich passe meinen Code im LaCrosse-Code auch noch an, dann können wir auch negative Temperaturen messen.

Grüße,
Jürgen

juergs

#329
Nach Analyse des Timings, hier die Einstellungen für PLL-Takt (Nicht 8MHz, ohne Divider):
Fuses: LF=0xF1 HF= 0xDF EF=0xFF Lock= 0x03

Zitat// NEU:
int iLongPulse  = 1300;
int iShortPulse  = 500;
int iDelay         = 1100;
Enspricht dem Timing von http://www.f6fbb.org/domo/sensors/tx_signals.php



Bit_0: 1,3ms HIGH + 1,0ms LOW => Gesamt: 2,3 ms
Bit_1: 0,5ms HIGH + 1,1ms LOW  => Gesamt: 1,6ms


Code ATtiny85_433MHz_LaCrosse_Temp

Je nach c-Compiler (!) scheint das hier der richtige cast von float auf int zu sein:
if (t> 0)
    {
        tens = ((int)t / 10) + 5;
        ones = ((int)t % 10);
        tenths = (int)(t * 10) % 10;
        printf("Tens: %d  ones: %d  tenths: %d\n", tens, ones, tenths);
    }
    else
    {
        t = 50 + t;
        printf("Float: %2.1f\n",t);
        tens = ((int)t / 10);
        ones = ((int)t % 10);
        tenths = (int) (t * 10) % 10;   
        //tenths = abs(tenths);
        printf("Zehner: %d  Einer: %d  Dezimale: %d\n",tens, ones, tenths);
    }



Positive temperaturen 32,5 °C:
ZitatHello, World. Testing temperatures below zero!
00001010000011011101100000100000100000101000
Float: 32.5
Tens: 8  ones: 2  tenths: 5

Negative Temperaturen -32,5°C:
ZitatHello, World. Testing temperatures below zero!
00001010000011011101001000100000001000101100
Float: -32.5
Float: 17.5
Zehner: 1  Einer: 7  Dezimale: 5

Ergibt in LaCrosse.cpp diese korrekte/funktionierende Methode CalcTemp:
//-----------------------------------
void LaCrosseClass::CalcTemp()
{
  if (t>= 0)
    {
        tens = ((int)t / 10) + 5;
        ones = ((int)t % 10);
        tenths = (int)(t * 10) % 10;       
    }
    else
    {
        //--- negative temperatures
        t = 50 + t;       
        tens = ((int)t / 10);
        ones = ((int)t % 10);
        tenths = (int) (t * 10) % 10;           
    }
  //--- we send a temperature id
  nible3 = COM_TEMP;
}
//-----------------------------------


Angehängtes Hex-File ist auf ID 80 compiliert.