Schnup89 / LIVY_RING_G2-Tasmota

25 stars 4 forks source link

[Code] Bewegungssensor Konfiguration #13

Closed Schnup89 closed 3 years ago

Schnup89 commented 3 years ago

Um die Sensitivität und ggf. die "Blind-Time" anzupassen (am einfachsten per Tasmota-Rule) brauche ich Hilfe bei dem Zusammensetzen des HEX-Strings für die Konfiguration:

 //see https://media.digikey.com/pdf/Data%20Sheets/Excelitas%20PDFs/PYQ1648-7052.pdf
    // | 8bit sensitivity | 4bit blind time | 2bit pulse counter | 2bit window time | 2bit operatin mode | 2bit filter source | 5bit reserved |
    //00011000 0100 01 10 10 00 10000
#define PYQ1548_HexConf           0x00304D10

Wie wäre die Vorgehensweise wenn ich die 8bit sensitivity und 4bit bild time per variable anpassen möchte?

Ich habe es mit einem Structed und verkleinerten unit8_t felder versucht, aber ohne Erfolg.

Sensor: https://github.com/Jason2866/LIVY_RING_G2-Tasmota/blob/work/tasmota/xsns_90_pyq1548.ino

Jason2866 commented 3 years ago

Hallo, danke für die Blumen. Ich bin aber weit davon entfernt programmieren zu können. Ich kenne mich nur etwas mit dem Unterbau (Espressif IDF und Arduino) und PlatformIO aus. Ping in Discord channel #compiling @barbudor an. Er kennt den Tasmota Code gut und hilft

barbudor commented 3 years ago

What a joke, someone who knows Tasmota better than me is pulling my leg in a language I don't understand 🤣 🤣 🤣 🤣 🤣 🤣

Schnup89 commented 3 years ago

🤣 Yeah so, I need some help with the PIR-Sensor PYQ1648 which is controlled by an "Directlink" Interface. Found a library for that and included it as a new Sensor for Tasmota.

The Configuration is sent with a fixed HEX-String and I need to figure out how I can set the sensitivity, blind time pulse counter etc. with a variable or a struct.

The struct could be like that:

struct pyqConf {
{
  uint8_t  sens;
  uint8_t  blind:4;
  uint8_t  pulse:2;
  uint8_t  wndw:2;
  uint8_t  oper:2;
  uint8_t  filter:2;
  uint8_t  res:5;
}
pycconf;

I would set some default values and then change them if tasmota rules are created by the user.

The main problem is that I have no clue how to get a HEX String from that struct which would be like this:

define PYQ1548_HexConf 0x00304D10

Thank you for your help

barbudor commented 3 years ago

Hi @Schnup89 , I'll do my best Can you confirm that this is the right datasheet https://www.excelitas.com/product/pyq-1548-quad-element-low-power-digipyro I will read the datasheet and come back to you. Are the files currently on your repo up to date ? You know it is easier to do a fork of the full repository and create your own development branch like "dev_PYQ1648". It will make it easier to then submit a PR to have this integrated in Tasmota.

barbudor commented 3 years ago

you wrote //see https://media.digikey.com/pdf/Data%20Sheets/Excelitas%20PDFs/PYQ1648-7052.pdf But you said it is a PYQ1548 So that wouldn't be the right datasheet

Can you please confirm the part reference ?

Schnup89 commented 3 years ago

https://media.digikey.com/pdf/Data%20Sheets/Excelitas%20PDFs/PYQ_1548_7660_Apr17,2019_DS.pdf

It's this one, the sensor ist marked with the number 7660

Edit: I didn't used github that much so I have to take some time to get into it ;)

barbudor commented 3 years ago

Ok, the one I found at the manufacturer web site is more recent (6/4/2021) & no problems, Jason gave me access to the repo I'll be back soon

barbudor commented 3 years ago

ok, I Pushed a change to the repo. I hops this is what you were looking for:

#define PYQ1548_DEFAULT_CONFIG            0x00304D10

typedef union {
  uint32_t regval;
  struct {
      uint32_t count_mode:1;           // bit [0]
      uint32_t _must_set_to_0:1;       // bit [1]
      uint32_t hpf_cut_off:1;          // bit [2]
      uint32_t _must_set_to_2:2;       // bits [4..3]
      uint32_t signal_source:2;        // bits [6..5]
      uint32_t operation_mode:2;       // bits [8..7]
      uint32_t window_time:2;          // bits [10..9]
      uint32_t pulse_counter:2;        // bits [12..11]
      uint32_t blind_time:4;           // bits [16..13]
      uint32_t threshold:8;            // bits [24..17]
  } field;

} PYQ1548_Config_t;

PYQ1548_Config_t PYQ1548_Config = { .regval = PYQ1548_DEFAULT_CONFIG };
00:00:00.145 PYQ1548: regval = 0x00304D10
00:00:00.146 PYQ1548: count_mode [0] = 0
00:00:00.148 PYQ1548: hpf cut off [2] = 0
00:00:00.152 PYQ1548: signal source [6..5] = 0
00:00:00.156 PYQ1548: op mode [8..7] = 2
00:00:00.160 PYQ1548: window time [10..9] = 2
00:00:00.164 PYQ1548: pulse counter [12..11] = 1
00:00:00.168 PYQ1548: blind time [16..13] = 2
00:00:00.172 PYQ1548: threshold [24..17] = 24

1) When assigning fields in a structure on a little-endian CPU, you must start from the LSB. So in the opposite order of what you tried 2) I added as a union so it is easy to access also the uint32 regval 3) As the fields are not aligned on bytes, they must be of type uint32_t and not uint8_t otherwise the compiler align them on bytes boundary.

Schnup89 commented 3 years ago

Thank you very much, also for the adjustments at the other sensors. I've just tested the code and it works perfectly.

There are a lot of things to think about, but finally it looks nice and understandable! Next step is to implement the Tasmota-Rules for some of useful fields.

I've read somewhere that tasmota rules should be used for storing configuration variables for sensors, is that the way to go? If yes, do you have an example sensor which ist using rules for storing configurations?

barbudor commented 3 years ago

Hi A driver can be configured dynamically using commands. Many sensor drivers use the command Sensor<x> for that purpose where x is the number of the sensor's driver. In your case, the number is currently 90. By adding those lines in the case of Xsns90() you can add a Sensor90 command handler:

      case FUNC_COMMAND_SENSOR:
        if (XSNS_90 == XdrvMailbox.index) {
          result = PYQ1548CommandSensor();
        }
        break;

The function can look like:

bool PYQ1548CommandSensor(void)
{
...
  return true;
}

The content of the function depends on the syntax that you chose for the command. It could be one of:

  1. A single command to set all parameters using the hex code: Sensor90 0x00304D10 Easy to code but you are pushing back the complexity to the user which is not very nice
  2. A single syntax for all parameters individually in a list such as Sensor90 <count_mode> <threshold> <blind_time> ... which means that you would have to always provide all the parameters at every call. Or eventually, order the parameters so that the most important ones are at the beginning and make later parameters optionals.
  3. A command per parameter using either a number or a name to identifiy the parameter: Sensor90 8 34 to set threshold to 34 Sensor90 blind_time 4 to set blind_time to 4 Using a name needs more code but make the command more readable

It can also be a mix of 1 and 2: by checking the number of arguments to the command, you can decide if it is case 1 or case 2

Once you have such command, a basic of restoring the setting upon restart is to use a rule triggered by ON System#Bootto apply your setting, such as:

Rule 1 ON System#Boot DO Sensor90 0x00304D10 ENDON
Rule 1 1

Using which ever variant of the Sensor90 command you have decided to use. Is you chose case 2) above that would be something like:

Rule 1 ON System#Boot DO Backlog Sensor90 threshold 34; Sensor90 blind_time 4 ENDON
Rule 1 1

to have multiple Sensor90 commands

This is good for drivers which are used by very low number of people because that avoid freezing some space in the Settings area to save the data. If you driver is considered important enough, you could ask Theo to assign a uint32_t in the setting area to save the configuration word (not each field individually, this is not needed as the structure can allow that any time).

Many drivers implements such Sensor<x> commands. Look at the list in the doc here : https://tasmota.github.io/docs/Commands/#sensor13 Then look at the code of the driver for which the commands looks like the most what you want to implement.

I hope this is clear. Let me know if you need help with that.

Schnup89 commented 3 years ago

Ahh perfect, I used that for the the other sensor (MCP4706), thank you again for the explanation!

Schnup89 commented 3 years ago

User Controlled Parameters implemented, description on Readme Sensor90 sens, 30 Sensor90 blind, 2 Sensor90 pulse, 1