Sound level sensor

I used the new file and converted it to ESP32 just like the last one. I changed the 1024 to 4096:

static st::PS_SoundPressureLevel sensor1(F("soundPressureLevel1"), 30, 0, PIN_SPL, 0, 4096, 0.0, 165.0, 50);

Still getting a pretty large value for the sound level, and only one update. Plus, it says 30 seconds above, but if you note the timestamps, it's only checking in once a minute.

How are you calculating the SPL? It should be the voltage * 50. I didn't see anywhere in your code where this was happening.

I was just thinking, when my kids become teenagers, this house is pretty much partyproof, unlike my parent's house was. :slight_smile:

Edit: hold up, looks like the pinout I was looking at might have been incorrect.

Edit 2: Looks like it's fine. The pinout image I was looking at for this board has 3 GND pins. But one of them on the board is labeled "SND". I switched it to another pin, but no change. I'm getting checkins, but no soundPressureLevel attribute updates.

Edit 3: Pin problem! I was using A19/pin 26. Switched it to pin 36 and now it works. Here's the pinouts for my board:

Here's the events:

If I change the polling interval to something like 1 or 2 seconds, what will happen? Is that all I need to change? Is it going to hammer my HE to death? In order to change behavior, I need the consequences to be pretty immediate.

Is the contact sensor implemented yet? If not, that's probably fine. I can just create a rule that compares the value instead.

It doesn't seem to close the contact when I make a bunch of noise. I have this for now:

Hehehehehehe.

Is this how the PS_Illuminance library works too? If not, could it? I tried to implement a lum sensor a while ago and it wasn't very consistent. I had a feeling if the a cloud happened to be passing over or a bird was flying by I seemed to get vastly different readings. But it also could have been my sensor. But if this type of architecture isn't used for the lum library, that would totally explain my odd results.

Yes, sending data to Hubitat every 1-2 seconds is excessive and may lead to problems on your hub. I wouldn't do that. That is why I spent hours last night writing a new PS_SoundPressureLevel device for you that still reads the analog input very quickly, but can be controlled as to how frequently data is sent to the hub. I understand the desire for instant feedback to the little ones, but is 15 to 30 seconds really that much of a delay?

Yes, the contact sensor feature is implemented inside the Groovy Driver for the Sound Pressure Level child device. Did you configure the user setting for the SPL threshold in the child device?

No, the Illuminance device just reads the sensor value and transmits the result. There is no logic built into that device to perform filtering/averaging. If you want a more sophisticated illuminance sensor you could simply use the PS_Voltage device, but still use the "illuminance1" name when you declare it in the setup() routine of the sketch. The PS_Voltage device has a lot of options for filtering that will help eliminate high levels of variability. Just read through the comments at the top of the PS_Voltage.cpp file for all of the details.

I did configure the threshold. However, under current states in the device screen, there is no attribute listed for contact. And, when I exceed the threshold, the rule I had that used it never triggers.

Please show me a screenshot of the Device Details page for the Sound Pressure Level device. I tested it last night and the contact sensor works perfectly, assuming you set the max spl value and SAVE the device afterwards. Then, it simply needs an update from the HubDuino board to populate the contact sensor attribute on the screen.

See...that's why you're the master and I'm still the Padawan. :wink: That's brilliant! I will give that a try later today. Thanks!!

Threshold set to 75 and saved. I even went back out of it and back in to make sure. Just tripped it with a 93db clap.

Also seeing a bunch of these in the logs:

Try entering 75.0 instead of just 75 and see if that clears up the error. I will debug that issue later tonight.

I changed line 57 to this:

        if (tmpValue >= Float.valueOf(maxSPL)) {

This seems to have fixed the problem. The contact sensor seems to be working now.

1 Like

Thanks, I updated my GitHub repo with that change.

@signal15, based on my understanding of what you are attempting to do, perhaps look into comparator circuit. You can use voltage divider as a reference voltage. One of the resistor should be potentiometer so that you can adjust the reference. The spl output can go to the non inverting of the comparator. The output of the comparator is basically digital input to your MCU.

This will free up your MCU cycle to do something else. It does not have to loop very frequently.

A lot of MCU have built in comparator. There is probably no need to buy an external IC. You most likely need external voltage divider.

There is a weakness on that circuit I mentioned. If the SPL level is around the reference voltage, you can potentially be blasted with a lot of notification as the SPL dip and rise around the reference voltage. There is a couple solution. You can use something like de-bouncer logic in the software side on the MCU. Or(/and), You can implement a hysteresis using schmitt trigger IC as your comparator.

Interesting idea. I like the way you think! :slight_smile:

The code that reads digital inputs within HubDuino reads all digital inputs defined in the sketch every time through the Arduino loop() routine. So, I don't believe there would be much CPU savings.

I really don't believe the ESP32 is very busy, as I set the analog scans to only happen every 50ms by default. I have an Arduino MEGA board, with a much, much slower processors than an ESP8266, let alone an ESP32, that has no problem scanning I/O at a high frequency and still handling all of the other tasks (e.g. network communications).

My goal was to provide an easy method to fine tune the SPL maximum level via the Hubitat Device versus having to rebuild the code and update the ESP32 board each time an adjustment was required.

1 Like

Oops, I think I jump ahead too far. In most MCU, digital input may not need to be poll. You can use interrupt to be notified when the pin change. If there is no change, there is nothing to be processed. The benefit of the interrupt is I believe most MCU can be put to "deep sleep" mode and then woken up by the interrupt.

I agree. Reading an digital input is cheap. Reading an analog input by today MCU should be cheap. But, using the interrupt basically can free up the MCU either to sleep or do other stuff while the threshold is not crossed.

1 Like

Yes, I love using interrupts as well. However, creating a reusable platform that works across a multitude of MCU’s often requires compromises at the expense of optimizations. Some MCU’s only allow interrupts on a subset of pins. So, my Arduino library works around these limitations by using features common to all platforms.

1 Like

Rather than use a contact sensor, have you thought of using the soundSensor capability? I didn't even know this one existed!

image

I thought about it, but figured the contact sensor would be easier to use in almost every app...

1 Like

Always being so practical. Let your hair down! (No, I know what you mean. I just had no idea that one existed.)

Well, preliminary results showed that this thing works.... It shut off once automatically earlier this morning, and the kids were quiet all day. Normally I would have had to tell them at least 5 times to keep it down. :slight_smile: Thanks @ogiewon!

4 Likes