Help needed on noise on 1-wire dallas_temp caused by fan

Hi,

I am hacking into an Chinese led aquarium lamp with an ESP8266 on board.
The pcb has an temp output I located on GPIO14. I programmed a dallas_temp to it.
I also have a low side PWM fan connected by transistor to GPIO3.

But when the fan is on, it gives noise on the dallas temp.
I tried pausing the fan, which works, but the change in fan speed drives me crazy.

As in my second still original lamp, the fan doesn’t turn of, and temp reading is stable, there has to be a way of making it work without stopping the fan.
AI is of nu use in this as I tried it for the last couple of days.

This is a log file when the fan is turning and messing up the dallas_temp.

 [21:32:49.976][D][dallas.temp.sensor:128]: Scratch pad: F7.41.55.00.7F.FF.0C.51.3F (E0)
[21:32:59.000][W][component:462]: dallas_temp.sensor cleared Warning flag
[21:33:00.166][W][component:431]: dallas_temp.sensor set Warning flag: scratch pad checksum invalid
[21:33:00.167][D][dallas.temp.sensor:128]: Scratch pad: F7.01.55.40.7F.FF.4C.14.7F (2C)
[21:33:08.710][I][safe_mode:071]: Boot seems successful; resetting boot loop counter
[21:33:09.297][W][component:462]: dallas_temp.sensor cleared Warning flag
[21:33:09.781][W][component:431]: dallas_temp.sensor set Warning flag: scratch pad checksum invalid
[21:33:09.781][D][dallas.temp.sensor:128]: Scratch pad: F8.05.55.00.7F.FF.4C.14.C5 (CB)
[21:33:19.429][W][component:462]: dallas_temp.sensor cleared Warning flag
[21:33:19.922][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.500000°C
[21:33:30.170][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.437500°C
[21:33:39.823][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.437500°C
[21:33:49.768][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.437500°C
[21:34:00.096][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.375000°C
[21:34:10.143][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.375000°C
[21:34:19.769][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.375000°C
[21:34:30.080][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.375000°C
[21:34:40.069][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.312500°C
[21:34:49.771][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.312500°C
[21:34:59.935][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.250000°C
[21:35:10.037][D][dallas.temp.sensor:054]: 'Lamp Temp': Got Temperature=31.250000°C
[21:35:19.782][W][component:431]: dallas_temp.sensor set Warning flag: scratch pad checksum invalid
[21:35:19.789][D][dallas.temp.sensor:128]: Scratch pad: FF.FF.FF.FF.FF.FF.FF.FF.FF (C9)
[21:35:29.408][W][component:462]: dallas_temp.sensor cleared Warning flag
[21:35:29.781][W][component:431]: dallas_temp.sensor set Warning flag: scratch pad checksum invalid
[21:35:29.781][D][dallas.temp.sensor:128]: Scratch pad: F3.23.75.00.7F.FF.0E.12.2A (24)
[21:35:39.483][W][component:462]: dallas_temp.sensor cleared Warning flag
[21:35:39.788][W][component:431]: dallas_temp.sensor set Warning flag: scratch pad checksum invalid
[21:35:39.788][D][dallas.temp.sensor:128]: Scratch pad: F3.01.55.04.7F.FF.0C.50.2A (73)
[21:35:49.158][W][component:462]: dallas_temp.sensor cleared Warning flag

This is the YMAL code connected to the dallas and the fan where the fan gets paused to make a measurement.

globals:
  - id: meting_bezig
    type: bool
    restore_value: no
    initial_value: 'false'
  - id: lamp_uit_tijd
    type: uint32_t
    restore_value: no
    initial_value: '0'
  - id: fan_speed
    type: float
    restore_value: no
    initial_value: '0.0'

one_wire:
  - platform: gpio
    pin:
      number: GPIO14
      mode:
        input: true
        pullup: true
    id: ow_gpio14

sensor:
  - platform: dallas_temp
    one_wire_id: ow_gpio14
    index: 0
    name: "Lamp Temp"
    id: lamp_temp
    update_interval: never

  - platform: template
    name: "Fan snelheid"
    unit_of_measurement: "%"
    update_interval: 5s
    lambda: return id(fan_speed) * 100.0;

Output:
  - platform: esp8266_pwm
    pin: GPIO3
    id: fan_pwm
    frequency: 25000 Hz

interval:
  - interval: 10s
    then:
      - lambda: |-
          if (id(fan_speed) == 0.0) return;
          id(meting_bezig) = true;
      - output.turn_off: fan_pwm
      - delay: 100ms
      - component.update: lamp_temp
      - delay: 1000ms
      - output.turn_on: fan_pwm
      - lambda: id(meting_bezig) = false;
  
  - interval: 500ms
    then:
      - lambda: |-
          float pot = id(light_pot).state;

          auto time = id(ha_time).now();
          int uur = time.hour;
          bool schema_aan = (uur >= 15 && uur < 22);

          bool schema_override_uit = (pot >= 0.1 && pot < 0.2);
          bool schema_override_aan = (pot >= 0.2);

          bool lamp_aan;
          if (schema_override_aan) {
            lamp_aan = true;
          } else if (schema_override_uit) {
            lamp_aan = false;
          } else {
            lamp_aan = schema_aan;
          }

          if (lamp_aan) {
            id(lamp_uit_tijd) = 0;
          } else if (id(lamp_uit_tijd) == 0) {
            id(lamp_uit_tijd) = millis();
          }

          bool fan_aan = lamp_aan || (id(lamp_uit_tijd) > 0 && (millis() - id(lamp_uit_tijd)) < 120000);

          float temp = id(lamp_temp).state;
          float fan_target = id(fan_speed);

          if (!isnan(temp)) {
            if (temp < 40) {
              fan_target = 0.6;
            } else if (temp < 50) {
              fan_target = 0.8;
            } else {
              fan_target = 1.0;
            }
          }

          if (!id(meting_bezig)) {
            if (fan_aan) {
              id(fan_pwm).set_level(fan_target);
              id(fan_speed) = fan_target;
              id(status_led).turn_on();
            } else {
              id(fan_pwm).set_level(0.0);
              id(fan_speed) = 0.0;
              id(status_led).turn_off();
            }
          }

While you tried to describe the situation, it remains unclear to me.
Are there any differences on hardware side between “working” and “not working”?

to add to this. Are you overloading the circuit of the lamp? Are those warning flags are for noise interferences or something else?

This is historically a problem with powerline technologies like X10 or Insteon. The symptom is that automation can turn things on, but can’t turn them back off because noise is introduced by the load when powered up.

While I don’t have a particular one to recommend, something to research is a noise filter for the fan to dampen its noise.

No, hardware is 100% the same. I am only flashing new software.

I didn’t ask that…
Anyway,
make sure that your fan power wiring is far as possible from sensor wiring.
-sensor has ~4k7 external pullup.
-fan has flyback diode and ideally also 100uf cap across the contacts.
-lower your pwm frequency.

1 Like

I am sorry, I dont understand what you then mean with “differences on hardware side”. The original lamp and the flashed lamp are 100% the same. It is 1 pcb with an esp soldered to it. No hardware changes have been done.

So all “wiring” is done on the pcb and cant be changed (not easily). There is just 1 connector leading to the fan and 1 connector leading to the led.

Ok, clear.
Did you try to play with pwm frequency? “Non-pwm fans” driven with transistor circuit often use very low frequency even down to double digit Hz.

No, the circuit is not overloaded - I replaced only the firmware, the hardware load is identical to the original lamp (same LEDs, same fan).

The scratch pad checksum invalid warnings indicate that the DS18B20 transmitted data but the CRC check failed - the received bytes don’t match the expected checksum. There are two possible causes:

  1. Electrical noise - the fan PWM signal induces interference on the 1-Wire data line, causing bits to flip during transmission. This is what I suspected initially.

  2. Power supply instability - if the 3.3V rail from the LM1117 regulator is not stable enough under load, the DS18B20 could produce corrupted data regardless of noise on the data line.

What makes me think it might be option 2 is the FF.FF.FF.FF.FF.FF.FF.FF.FF patterns that appear occasionally - the sensor returns all ones, as if it’s not responding at all, almost like it loses power momentarily when the fan PWM switches.

I’ve partially solved it by pausing the fan PWM during measurement (100ms before, 1000ms after triggering the conversion to allow the full 750ms conversion time to complete), combined with a flag that prevents the 500ms main loop from restarting the fan during the measurement window. This reduced errors significantly but didn’t eliminate them entirely.

Another option is poor quality sensor. Seen many posts on Chinese clones producing inconsistent readings. I have a temp sensor in my solar shed and it works without issue. Very noisy environment with inverter, charge controllers & multiple fans.

I can’t see that it would make a difference but I have only ever used the sensor address in my code while you are using index method.

I found the solution.
I didnt want to compile every time for a new PWM frequendy, I changed to analogWrite() and analogWriteFreq() so I could adjust the frequency in HA.
This imediatly fixed the issue of interference!

So the fix was to replace all esp8266_pwm outputs with direct Arduino analogWrite() and analogWriteFreq() calls inside a lambda. This uses a different, simpler PWM implementation without the interrupt overhead, and the 1-Wire sensor now reads reliably at any PWM frequency — even 25kHz — with no pausing or workarounds needed.

For my curiosity, did you try sub 1khz with esphome native component?

Yes, also did seam to fix the problem. Tried at 20 and 50Hz. But I wanted to know what the best frequency was for interference to fan noise ratio. So switched to the analogwrite to be able make it switch in HA without compiling.

I am now running into API disconnects and reboots. So I might switch back to standard PWM with low frequenties.

I suspect it wasn’t noise, but rather the interrupting. OneWire is bit-banged and timing is important for the bits. Getting an interrupt in the middle of one will screw up the timing.