Teensy 4.1 PWM to NPN for fan speed control? - Page 1
Forum section: electronics / projects

author: ryanmills
author_rank: Unknown
timestamp: April 29, 2022, 02:30:56 am
content: Shift Register Datasheet:https://www.ti.com/lit/ds/symlink/tpic6a595.pdfNPN Datasheet:https://www.diodes.com/assets/Datasheets/FZT1053A.pdfI have the above connect to a Teensy 4.1. Note there is a 1k current limiting resistor on the PWM pin. Everything works but the NPN (Q1) tied to all the PGND's does not seem to control the fan speed at all, they always run at 100%. In fact it seems to do nothing and now I'm wondering if I mis-read the Shift Register Datasheet? The logic diagram reads like all the output transistors go to PGND so if I put an NPN on the PGND I thought I could use it as a global speed control. Reading the datasheet again now I still don't see why this does not work and where the fans are pulling GND if the NPN is off. I scoped the PWM pin (Pin 4) and its working, duty cycles change as expected. I will include the rough class that drives it, but it's pretty light, basic shiftOut and analogWrite in case I missed something simple in the code. I swapped the NPN thinking maybe I blew it testing something else but even on a fresh one the fans always work 100% when on.Code:#include <Arduino.h>#include "SolarPins.h"#include "SolarOutputs.h"void SolarOutputs::begin(){Serial.println("SolarOutputs()");pinMode(SR2_RCK, OUTPUT); //latchPinpinMode(SR2_SRCK, OUTPUT); //clockPinpinMode(SR2_DS, OUTPUT); //dataPinpinMode(OUTPUT_POWER, OUTPUT);analogWrite(OUTPUT_POWER, 0);this->update();}void SolarOutputs::update(){byte set_byte = 0b10000000;for (int i = 0; i < 8; i++){bitWrite(set_byte, i, this->outputs);}digitalWrite(SR2_RCK, LOW);delay(5);shiftOut(SR2_DS, SR2_SRCK, MSBFIRST, set_byte);delay(5);digitalWrite(SR2_RCK, HIGH);}void SolarOutputs::set_power(int power){double base = power;double power_level = (base/100) * 255; // convert percent to doubleint power_level_int = power_level; // double to intanalogWrite(OUTPUT_POWER, power_level_int);}void SolarOutputs::set_output(int bit, int value){this->outputs = value;this->update();}void SolarOutputs::kill(){analogWrite(OUTPUT_POWER, LOW);}

author: ryanmills
author_rank: Unknown
timestamp: April 29, 2022, 02:36:57 am
content: Looking again maybe I did this backwards and the correct way was to tie all the PGNDs directly to ground and drive the G (pin 4) directly with the PWM wire? I think that would do the same thing and act as global control?

author: NiHaoMike
author_rank: Super Contributor
timestamp: April 29, 2022, 02:40:57 am
content: Quote from: ryanmills on April 29, 2022, 02:36:57 amThat would be correct.

author: Ian.M
author_rank: Super Contributor
timestamp: April 29, 2022, 03:29:44 am
content: Yes, PWMing /G is the standard way to apply common duty cycle control to a TPIC6x595. Don't forget its active low so you need to invert the PWM either is software or hardware.The front page of the datasheet says:Quotewhich I would interpret as its forbidden to switch PGND (as it must remain connected to LGND). There's probably only a diode junction isolating the two grounds which is fine as long as there's no more than a couple of hundred millivolts peak difference between them. You are lucky the chip survived as uncontrolled current flow in the substrate of a CMOS chip can trigger latch-up.

author: ryanmills
author_rank: Unknown
timestamp: April 29, 2022, 03:53:14 am
content: Quote from: Ian.M on April 29, 2022, 03:29:44 amOhh that is a good catch, I missed needing to invert the PWM, not sure I can do that without hardware on a teensy. Thank you, i will look into that.

author: ledtester
author_rank: Super Contributor
timestamp: April 29, 2022, 05:38:27 am
content: Quote from: ryanmills on April 29, 2022, 03:53:14 amI think that's as simple as using the complementary duty cycle, ie. instead of an 80% duty cycle set the output for 20%, etc.