generating pulsesequence on GPIO

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

generating pulsesequence on GPIO

#1 Post by stepfl » 19 May 2022, 07:13

sorry - I'm very new with EspEasy - up to now I was using Tasmota or Micropython. BUT - EspEasy seems to be very interesting for my project(s)!

NOW I've to connect ESP to a special Controller which has only a kind of PulseCounter as entry. So I try to generate/convert the measured Value to a pulsesequence.
The MaxFrequency of the entry is fixed to 10Hz ....

It should be something like:
Value:= 15 ==> pulsecode: (Startsequence): 1s:ON + 1s:OFF + (Value): 15 x ( 50ms ON / 50 ms:OFF) + (EndSequence): 1s:ON + 1s:OFF => OFF (default)....

i tried to do it like:

Code: Select all

// [VAR#4] : measured Value / START:pulldown GPIO#2
on GPIO#2 do
  if [VAR#4]>0 and [GPIO#2]=1 
    delay 50
    gpio,2,0
  elseif [VAR#4]>0 and [GPIO#2]=0
    delay 50
    let,4,[VAR#4]-1
    gpio,2,1
  elseif  [VAR#4]=0 and [GPIO#2]=0
    delay 1000
    gpio,2,1
  else
    delay 1000
  endif
EndOn
I did not find anything like "while....loop" or a trigger like "on VAR#2 do" ....
So I have no Idea how to realise this within EspEasy ... and need your support...

stepfl

ps. Sorry about my english - i'm not used to write english

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: generating pulsesequence on GPIO

#2 Post by TD-er » 19 May 2022, 09:46

Calling delay in rules is not a good idea as it is blocking everything else.
Also when handling an event sent by the GPIO (assuming you used "monitor" to trigger events on GPIO changes for that specific pins), the state of the pin from the moment the event was triggered is included in the event.

The event is like GPIO#2=1
This means it is better to evaluate using %eventvalue1% instead of [gpio#2] as the latter one may have changed in the mean time.

You can create a looptimer, even with a fixed nr of loops.
There is also a looptimerset_ms for millisec resolution.
See: https://espeasy.readthedocs.io/en/lates ... oop-timers

stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

Re: generating pulsesequence on GPIO

#3 Post by stepfl » 19 May 2022, 10:01

thanks a lot ....
YES - i know ... to use delay is not a good idea ... and checking the GPIO too... this was the result of my "don't know how to..."

looptimerset_ms seems to be the solution - a easy one too ... I'll try it this evening ... thanks a lot!

AND .... the stuff of how it works with "eventvalue1% - i don't understand ... probably because my English is really not the best...

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: generating pulsesequence on GPIO

#4 Post by TD-er » 19 May 2022, 10:51

Just a very short explanation.

Events can have 0 or more event values.
For example, a task reporting a new sample of a sensor typically sends out events like this (task is called "bme", task value is "temp", or whatever you named them)
bme#temp=12.34

You can act on this in the rules like this:

Code: Select all

on bme#temp do
  logentry,"Temperature is %eventvalue1% degree C"
endon
This will send out a log with a string like this: "Temperature is 12.34 degree C"
As you can see, the %eventvalue1% is replaced by the 1st event value (the first value after the = in the full event)

Other events may have multiple event values, like when you check the checkbox in a task to send all values in a single event:
bme#All=12.34,76.0,1023.4

If memory serves me well, then the order of the values from the BME280 sensor will be sent in the order of temp/hum/pressure.
Thus %eventvalue1% = 12.34
%eventvalue2% = 76.0 (humidity)
%eventvalue3% = 1023.4 (barometric pressure)

See also: https://espeasy.readthedocs.io/en/lates ... eventvalue

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: generating pulsesequence on GPIO

#5 Post by TD-er » 19 May 2022, 10:52

By the way, if you need short timings for the looptimer, please use the latest build as the rules processing speed has significantly improved.

stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

Re: generating pulsesequence on GPIO

#6 Post by stepfl » 19 May 2022, 12:55

my first trial of ... :
actual i use GPIO2 becaus of the LED :_)

to change easily the TimeValues i use:
VAR#7:Time of Start-/StopSequencePulse (actual 2000ms),
VAR#6: Time of DataSequencePulse (actual 200ms) /
VAR#5: defines START / DATA / STOP
VAR#4: Value to be send

Code: Select all

// Output: PulseSequenz of VAR#4 
On Rules#Timer=1 do
  if [var#5] = [VAR#7]   // START
    timerset_ms,1,[VAR#5]*2
    pulse,2,0,[VAR#5]
    if [VAR#4]>0
      let,5,[VAR#6]      // Data
    endif
  elseif [var#5] = [VAR#6]
    timerset_ms,1,[VAR#5]*2
    pulse,2,0,[VAR#5]
    let 4,[VAR#4]-1
    if [VAR#4]= 0
      let,5,0
      pulse,2,0,[VAR#7]  // STOP
      timerset_ms,1,[VAR#7]*2
    endif
  else
    GPIO,2,1
    timerset_ms,1,0
 endif
endon
it seems to work fine

Question:
Does "Pulse" also blocking everything else? ...

"by the way" .... yes I do it - i flashed just few days ago ... THANKS für your help!!!

stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

Re: generating pulsesequence on GPIO

#7 Post by stepfl » 19 May 2022, 13:40

probably you could be so nice and check the other part .... calulation of a moving average...

the Reason:
the Data of VL53L0X ( 100mmm ... 1600mm) jump a lot and I didn't want to wait too long for the first usable Data...
VAR#10: actual runnicng counter of MWs in the sum of MWs (VAR#1)
VAR#2: actual moving average
VAR#4: Data to be send per PulseSequence

Code: Select all

On System#Boot do
  delay 50   
  let,3,50     // max Change (Messwert-Mittelwert)
  let,6,500   // MW-Puls [ms]
  let,7,1000 // Start/Stop-Pulse [ms]
  let,9,30     // maxCount MWs
  GPIO,2,1  //PulsData-Output
endon

// moving average:
On OilLevel#Distance Do   // VL53L0X - LaserDistanceSensor 

  // (Re-)START
  if [VAR#10]=0
    let,1,0
    Let,2,[VAR#1]
  endif

  // change to much > [VAR#3]
  if abs([OilLevel#Distance]-[VAR#2]) > [VAR#3]
     Let,10,1
     let,1,[OilLevel#Distance]
     let,2,[VAR#1]
  endif

  // Data-Sum
  if [VAR#10]<[VAR#9]
    Let,10,[VAR#10]+1
    Let,1,[VAR#1]+[OilLevel#Distance]
  else
    Let,1,round([VAR#1]*([VAR#10]-1)/[VAR#10])+[OilLevel#Distance]
  endif

  // Calc.moving Average:
  if round([VAR#1]/[VAR#10])!=[VAR#2]
    Let,2,round([VAR#1]/[VAR#10])
    if [VAR#5]=0 and [VAR#10] = [VAR#9]

      // START ImpulsSequenz
      Let,4,round([VAR#2]/10)  //Ausgabewert
      let,5,[VAR#7]  
      timerset_ms,1,0 // START PulsAusgabe
    endif
  endif
EndOn
It is probably not the best coding but it works ...
Have a good time !!!

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: generating pulsesequence on GPIO

#8 Post by TD-er » 19 May 2022, 14:03

stepfl wrote: 19 May 2022, 12:55 [...]
Question:
Does "Pulse" also blocking everything else? ...

"by the way" .... yes I do it - i flashed just few days ago ... THANKS für your help!!!
Yep pulse does "block" execution, where "longpulse" and "longpulse_ms" do not.
For very short pulses this does not really matter, but for those a bit longer than a few tens of msec it may be an issue.
On the other hand, the rules execution continues after starting the longpulse, so if you plan on doing things during this pulse with that GPIO pin, then you might see some unexpected behavior.

The same for "event" vs. "asyncevent"
It is best to call "asyncevent" from within the rules as that will queue the event to the eventqueue.
But on the other hand, sometimes you need to have things done right now, so then call "event".
Side effect is that it will block rules execution longer and when calling event from event recursively you may exceed the resources of the ESP and cause it to crash (or simply give an error...)

And for someone who just started with ESPEasy you're writing rather complex rules already.

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: generating pulsesequence on GPIO

#9 Post by TD-er » 19 May 2022, 14:28

stepfl wrote: 19 May 2022, 13:40 probably you could be so nice and check the other part .... calulation of a moving average...

the Reason:
the Data of VL53L0X ( 100mmm ... 1600mm) jump a lot and I didn't want to wait too long for the first usable Data...
VAR#10: actual runnicng counter of MWs in the sum of MWs (VAR#1)
VAR#2: actual moving average
VAR#4: Data to be send per PulseSequence

Code: Select all

On System#Boot do
  delay 50   
  let,3,50     // max Change (Messwert-Mittelwert)
  let,6,500   // MW-Puls [ms]
  let,7,1000 // Start/Stop-Pulse [ms]
  let,9,30     // maxCount MWs
  GPIO,2,1  //PulsData-Output
endon

// moving average:
On OilLevel#Distance Do   // VL53L0X - LaserDistanceSensor 

  // (Re-)START
  if [VAR#10]=0
    let,1,0
    Let,2,[VAR#1]
  endif

  // change to much > [VAR#3]
  if abs([OilLevel#Distance]-[VAR#2]) > [VAR#3]
     Let,10,1
     let,1,[OilLevel#Distance]
     let,2,[VAR#1]
  endif

  // Data-Sum
  if [VAR#10]<[VAR#9]
    Let,10,[VAR#10]+1
    Let,1,[VAR#1]+[OilLevel#Distance]
  else
    Let,1,round([VAR#1]*([VAR#10]-1)/[VAR#10])+[OilLevel#Distance]
  endif

  // Calc.moving Average:
  if round([VAR#1]/[VAR#10])!=[VAR#2]
    Let,2,round([VAR#1]/[VAR#10])
    if [VAR#5]=0 and [VAR#10] = [VAR#9]

      // START ImpulsSequenz
      Let,4,round([VAR#2]/10)  //Ausgabewert
      let,5,[VAR#7]  
      timerset_ms,1,0 // START PulsAusgabe
    endif
  endif
EndOn
It is probably not the best coding but it works ...
Have a good time !!!
You can also use some tricks like this:

Code: Select all

[var#[int#100]]
This can be used as an index over a row of variables.
So you know where to put the latest measured value and can subtract the old value at that position from the computed sum.
For example you have reserved var#101 .. 110 to keep track of the last 10 samples and #100 is the pointer to the current sample. (sum = #99 and count is #98
On a new sample you do something like this:

Code: Select all

if [int#98] > 0
  let,98,[int#98]-1 // decrease count
  let,99,[var#99] - [var#[int#100]] // Remove oldest from the sum
endif
let,98,[int#98]+1 // increment counter
let,99,[var#99] + %eventvalue1%
let,[int#100],%eventvalue1%
let,100,[int#100] + 1
if [int#100] > 110
  let,100,101
endif

stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

Re: generating pulsesequence on GPIO

#10 Post by stepfl » 19 May 2022, 19:09

this project should measure the Level of Oil in the Tank.
The LX... works very fine in the rang up to 1m then it starts to jump around. => moving average ...

The HeatingController (Heizungssteuerung) has not so many possibilities to enter the Oillevel-Data - the best way is to send PulseCodes ... but has a website to see what is going on

The Event from the LX..Device and of the PulsSequence doesn't fit very well - makes the PulseSequence jumping (stolpern) a litte bit.

The Oillevel doesn't jump - for shure ... so it would be no problem to have times without measurements..
So - i would like to disable the Sensor while sending the PulseSequence... is there any possibility to turn off this/a device ... and later on restart it ...
In Tasmota it was very nice to have alternative rules which you could turn on or of ... I didn't find similar command in EspEasy ...

Your other hints - i'll try them next weekend...

AND - again - thanks a lot for .... (everything)
Have a good evening, stepfl

User avatar
Ath
Normal user
Posts: 3415
Joined: 10 Jun 2018, 12:06
Location: NL

Re: generating pulsesequence on GPIO

#11 Post by Ath » 19 May 2022, 20:36

stepfl wrote: 19 May 2022, 19:09 this project should measure the Level of Oil in the Tank.
The LX... works very fine in the rang up to 1m then it starts to jump around. => moving average ...
Have you tried the VL53L1X? That has a range up to 4 meter, where the VL53L0X has a max range of 2 meter, suggesting that a VL53L1X could give more stable results in the range you need. It uses a different plugin but with a very similar feature set. (I wrote both plugins, using tried and proven Arduino libraries) The VL53L1X also has a 'Trigger delta' setting to even out small measurement inaccuracies.
stepfl wrote: 19 May 2022, 19:09 So - i would like to disable the Sensor while sending the PulseSequence... is there any possibility to turn off this/a device ... and later on restart it ...
That is what the commands "taskenable,<taskname_or_tasknumber>" and "taskdisable,<taskname_or_tasknumber>" are for ;)

Or an alternative could be to set a variable while sending out the pulse, so the event only starts a new send action if it is not set.

Code: Select all

on OilLevel#Distance do
  if [var#999] = 0
  ... existing code
  endif
endon
Then, just before starting the send action, use "Let,999,1" to inhibit a new trigger, and after completion of the send, use "Let,999,0" to re-enable it
/Ton (PayPal.me)

stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

Re: generating pulsesequence on GPIO

#12 Post by stepfl » 19 May 2022, 22:20

Ath wrote: 19 May 2022, 20:36 Have you tried the VL53L1X? That has a range up to 4 meter, where the VL53L0X has a max range of 2 meter ...
Yes I did and I 'll use it .... but - in this case (dimesion of the "Platine") I'll prefere the LX53L0X...
and the moving Average with enough points ist slowlier but is good enough...
Ath wrote: 19 May 2022, 20:36 That is what the commands "taskenable,<taskname_or_tasknumber>" and "taskdisable,<taskname_or_tasknumber>" are for ;)
hmmm ...
I'm not so trained in programming and even more in reading English texts ... for me it's hard work ;-)...
I read this stuff - but ... Where can i find the tasknumber or the Taskname ...? causes stress in my head ... :) (sorry) ... is it to be found in the device-table? ... or where???
Ath wrote: 19 May 2022, 20:36 Or an alternative could be to set a variable while sending out the pulse, so the event only starts a new send action if it is not set.

Code: Select all

on OilLevel#Distance do
  if [var#999] = 0
  ... existing code
  endif
endon
Then, just before starting the send action, use "Let,999,1" to inhibit a new trigger, and after completion of the send, use "Let,999,0" to re-enable it
This is the way i tried to realize it ... but it (PulsSequence) is still stumbling ... I think because other events needs their time too...

Have a good night - and I'm proud to talk woth one of the profies ... :))

User avatar
Ath
Normal user
Posts: 3415
Joined: 10 Jun 2018, 12:06
Location: NL

Re: generating pulsesequence on GPIO

#13 Post by Ath » 19 May 2022, 23:42

The Taskname is the Name you gave the device, the number is listed in the Devices list (1..12 on ESP8266, 1..32 for ESP32 device).

Time-critical stuff is quite hard to realize using rules, because of the text-processing of the script taking some time, even now that it has improved already very much in recent weeks.

The VL53L0X and VL53L1X are the same form-factor boards here, I had to use a magnifying glass to see the difference (and now I have marked them, of course ;))
/Ton (PayPal.me)

stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

Re: generating pulsesequence on GPIO

#14 Post by stepfl » 20 May 2022, 08:49

what is the reason formultible "rules set x" ?
Is there any difference in handling the code within different Rules Sets?
Thanks - stepfl

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: generating pulsesequence on GPIO

#15 Post by TD-er » 20 May 2022, 08:54

There used to be a limit of 2k on the size of the rules file.
This was due to the fact that when saving the file, it was sent as a HTTP POST, meaning it must be in memory of the ESP before saving it.
In practice on an ESP8266 this limit was even less (between 1500 and 1700 bytes) resulting in an incomplete saved file.
But now we use some JavaScript to "upload" the file in the background. So the ESP does not need to keep the entire file in memory and thus there is not really a limit in size anymore.
Still from a performance point of view, I would suggest to keep the file a bit small (<8k), expecially on ESP8266.

stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

Re: generating pulsesequence on GPIO

#16 Post by stepfl » 20 May 2022, 10:22

Thanks ....
so all rules sets are finally one big programm-area...
this is a big difference to Tasmota ... BUT EspEasy a a very nice stuff ... much to huge for my old brain ... THANKS A LOT !!!

AND: with <TaskDisable> and <TaskEnable> my project works fine .. THIS is the final code....(if somebody else is interested in) ...

Code: Select all

On System#Boot do
  GPIO,2,1
  delay 500
  let,100,60     // PulsOutput every xx sec
  let,110,3000   // Distance to ground to calc the real OilLevel
  let,111, 1.272 // ltr per  cm
  TaskEnable,1   // Start LX53L0X
  timerset,2,[VAR#100]  // Start PulseSequenceTimer
endon

// moving Average:
On LX53L0X#Distance Do
  GPIO,2,1
  // change to much > [VAR#3] => RESTART
  if abs([LX53L0X#Distance]-[VAR#2])>[VAR#3]
    Let,10,0
  endif  

  // (Re-)START
  if [VAR#10]=0
   GPIO,2,1
   Let,1,[LX53L0X#Distance]
   Let,2,[VAR#1]
   Let,3,50   // max Change (measured Value - moving average)
   Let,5,0
   Let,6,100  // length of Data-Puls [ms]
   Let,7,2000 // length of Start/Stop-Pulse [ms]
   Let,9,30   // max Number of Elements in moving Average
   Let,10,1
  endif
 
  // Calc of Moving Average and the reported Value VAR#4
  if [VAR#10]<[VAR#9]
   Let,10,[VAR#10]+1
   Let,1,[VAR#1]+[LX53L0X#Distance]
  else
   Let,1,round([VAR#1]*([VAR#10]-1)/[VAR#10])+[LX53L0X#Distance]
  endif

  Let,2,round([VAR#1]/[VAR#10]) 
  if [VAR#2]<=[VAR#110]-50
    Let,4,round(([VAR#110]-[VAR#2])/10)   // Oil [*10 ltr]
  else
    let,4,35  //  limit min.OilLevel 
  endif
  logentry,[VAR#4] "cm OilNiveau"
  let,112, round([Var#4]*[VAR#111])
  logentry,[VAR#112] "x10 ltr Heizöl"
EndOn

on Rules#Timer=2 do // Timer to start Report
 GPIO,2,1
 if [VAR#10]=[VAR#9] and [VAR#4]>30 
   TaskDisable,1
   GPIO,2,1
   Let,5,[VAR#7]
   delay 500
   timerset_ms,1,5
 else
   TaskEnable,1
 endif 
 timerset,2,[VAR#100] 
EndOn


// PulseSequenz- Output
On Rules#Timer=1 do
  timerset_ms,1,[VAR#5]*2
  pulse,2,0,[VAR#5]

  if [VAR#5] = [VAR#7]   // START
    let,5,[VAR#6]

  elseif [VAR#4]>0       // Data 
    let 4,[VAR#4]-1
    if [VAR#4]=0          //STOP
      let,5,0
      timerset_ms,1,[VAR#7]*2
      pulse,2,0,[VAR#7]
      TaskEnable,1
    endif
  endif
endon
Finally I'll change the GPIO for Output ... and fit all parameter to the real situation ...

byby ,, until the next problems ;-)
Last edited by stepfl on 20 May 2022, 10:53, edited 1 time in total.

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: generating pulsesequence on GPIO

#17 Post by TD-er » 20 May 2022, 10:34

Well you can see it as "a number of small program areas" as in principle you have a lot of blocks like these:

Code: Select all

on ... do

endon
Each of these are called on events.
Some of them are system generated like WiFi#connected and many more.
Some are generated from tasks, so they have the names you made up yourself like garden#temperature.
And you can also call events you think of yourself and write a rules block for them like for example:

Code: Select all

// Calling the event from somewhere
// The "123" is an eventvalue you just give along with the event
event,MyEvent=123

on MyEvent do
  logEntry,"Handling MyEvent, value is: %eventvalue1%"
endon
And on top of that, you can set variables which can be used anywhere else. These variables have a longer "lifespan" than the handling of the event itself.

It might seem a bit overwhelming at first, but what I'm trying to tell you is that you can start with very basic simple steps and then when you get the idea you can continue to expand.
It is nearly without limits and as soon as we found those I will make sure to help you overcome those limits by adding new features to it :)

stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

Re: generating pulsesequence on GPIO

#18 Post by stepfl » 20 May 2022, 11:04

thanks for all of this stuff....

BUT... ;-):
in Tasmote it is very fine to generate a kind of blocks of events (rule1 / rule2/ ...) - and by deactivating such a block all events written in it are disabled - or - activating/enable.
In my case I would have separated "DataCalculation" and "PulseCodeReport" in two "rules" and switched between them ....

This allows to write more variants of handling the same situation - depending on which block is activatet ...
Not necessary .. but sometimes helpful and nice

" waling on a high level" :-) ( a kind of german saying "Jammern auf hohem Niveau")

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: generating pulsesequence on GPIO

#19 Post by TD-er » 20 May 2022, 11:12

Well all the rules files are parsed in order.
So if you want to disable an event block, you may need to edit it, or add some small check to it using a variable.

I guess it can be a nice feature to disable or suppress events.
Not many requests have been for it.

User avatar
Ath
Normal user
Posts: 3415
Joined: 10 Jun 2018, 12:06
Location: NL

Re: generating pulsesequence on GPIO

#20 Post by Ath » 20 May 2022, 11:17

TD-er wrote: 20 May 2022, 11:12 I guess it can be a nice feature to disable or suppress events.
Not many requests have been for it.
... only by some ppl migrating from Tasmota ;)
/Ton (PayPal.me)

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: generating pulsesequence on GPIO

#21 Post by TD-er » 20 May 2022, 11:19

Well there have been requests to disable whole rule files, even from before Tasmota had their rules system as they have now.

stepfl
Normal user
Posts: 10
Joined: 19 May 2022, 06:51

Re: generating pulsesequence on GPIO

#22 Post by stepfl » 20 May 2022, 14:17

Ath wrote: 20 May 2022, 11:17
TD-er wrote: 20 May 2022, 11:12 I guess it can be a nice feature to disable or suppress events.
Not many requests have been for it.
... only by some ppl migrating from Tasmota ;)

NO !!! .... normally I use python / micropython ...

But i found this method/possibility very help- and powerful ... a kind of "Master-Device" to handle several other devices/events as a group .....

On the other hand EspEasy has many really powerful commands ... f.e. <TaskDisable> ....
so don't mind .... :D I'm glad ...

Post Reply

Who is online

Users browsing this forum: No registered users and 22 guests