I have recently completed my first PCB project, a PWM fan control for a Mercedes PWM radiator fan. It works well but currently requires an external timer relay to allow the fan to run for 30 seconds after shutting off the engine. So I looked up a timer circuits to see if I could integrate the timer relay into my circuit and I came up with several circuits using a 555 IC. I also found that the 555 can be used to generate a PWM signal.
That got me thinking. I am currently generating the PWM signal in code, which works well but limits me because I constantly need to be generating that PWM signal and doing anything else will screw it up. So if I could offload the PWM to another chip that would be a big help.
So the question is can the 555 take care of both the timer and the PWM at the same time, and I also see there is also a dual 556 IC. Another question is that most of the application for a timer relay circuit I have seen are using the 555 to turn on and off an actual relay used to turn on and off a 100W light bulb or something. I would like to run the Arduino Nano 33 BLE directly off the 555 without a relay. Space is critical in this box so relays are not the best solution.
Please understand, a lot of the discussions about the 555 I have read are a little beyond me, like austable, monostable. I would have thought I just want it to be stable.
The problem is the Mercedes fan runs at 10Hz PWM. When I had this running with an Uno type board, I was able to use a PWM library to generate the 10Hz PWM signal. I have since switched to a Nano 33 BLE wich is not compatible with the PWM library so I developed code to generate the PWM signal independent of hardware. I believe you helped me with that.
555 is obsolete, I just ordered two from Digikey? In any case nothing is chiseling the 555 in stone. Is there a more up to date alternative. This is a clean sheet of paper.
Well, there is absolutely no reason you shouldn't be able to support such a low frequency and do anything you like at the same time. I don't recall, though, where you stated the acceptable timing error.
Also it seems incredible that you would not consider using the Arduino for a fan timer. It's no problem at all.
Many legacy parts are still available for replacements or because legacy projects still reference them. It doesn't mean it's a good idea to use them.
The discussion is here. In one of the last few posts I found that, me trying to output serial data while doing this would increase the interval well beyond 0.1 sec. Currently I would like to never update the PWM duty cycle for at least 10 seconds so I can output and LED code to see what speed Im running at and which of the three sensors is driving it.
As far as using the Arduino for the timer, I need the timer turn itself off. I will have to think about that. Any ideas?
It never really was an issue until now. I understand there is a PWM library available for the Nano 33 BLE, but I did like the idea of having a non hardware dependent solution. It work great if you can use it but there are features I would like to add that make it not so desirable. I also haven't given up on the code method. I'm not very familiar with the language but I will be experimenting with ways around this. Also I have just seen that a Nano PWM library has just become available, so that is an option as well.
Getting the PWM to work is kind of a nice to have as I do feel I have options. Main focus is the timer shut off power to the Arduino. Currently this is done with this relay. It is these features I would like to integrate onto the board, hopefully in a solid state form. It would mean, bringing in a third wire into the PCB that is powered at all times. I guess I could keep the Arduino powered at all times and this could easily be done. The car battery drain may be small enough to be tolerable.
Definitely have more software experience than electronics. But this is the first time I ever used this software. So really about the same big zero. But I have plenty of time to play with all these options.
Thanks
const int RadPin = A0; // Radiator Input Thermister
const int CondPin = A1; // Condenser Input Thermister
const int AuxPin = A2; // Auxilary Input Not used at this time
const int FanPin = 9; // Set Fan pin
const int LedPin = LED_BUILTIN; // Set on board LED pin
const long period = 100; // cycle interval 10Hz = 100ms
// 10 bit temperature equivolents for radiator sensor
const int Rad20 = 444; //85C
const int Rad30 = 484; //90C
const int Rad40 = 524; //95C
const int Rad50 = 562; //100C
const int Rad60 = 599; //105C
const int Rad70 = 635; //110C
const int Rad80 = 668; //115C
const int Rad90 = 699; //120C
// 10 bit temperature equivolents for condenser sensor
const int Cnd20 = 391; //40C
const int Cnd30 = 440; //45C
const int Cnd40 = 489; //50C
const int Cnd50 = 537; //55C
const int Cnd60 = 583; //60C
const int Cnd70 = 627; //65C
const int Cnd80 = 668; //70C
const int Cnd90 = 706; //75C
const int Aux20 = 0;
const int Aux30 = 0;
const int Aux40 = 0;
const int Aux50 = 0;
const int Aux60 = 0;
const int Aux70 = 0;
const int Aux80 = 0;
const int Aux90 = 0;
int RadVals[6] = {0, 0, 0, 0, 0, 0};
int CondVals[6] = {0, 0, 0, 0, 0, 0};
int AuxVals[6] = {0, 0, 0, 0, 0, 0};
int RadSpeed = 10;
int CondSpeed = 10;
int AuxSpeed = 10;
int FanSpeed = 10; // Set fan to 10% PWM = off
int FanState = LOW;
long interval = 0;
unsigned long nextMillis;
unsigned long previousMillis = 0;
unsigned long currentMillis;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(FanPin, OUTPUT);
}
void loop() {
//put your main code here, to run repeatedly:
//this code prints sensor value to the console
//Serial.print("Rad pin input = "); Serial.println(RadVals[0]);
//Serial.print("Cond pin input = "); Serial.println(CondVals[0]);
//Serial.print("Aux pin input = "); Serial.println(AuxVals[0]);
//Serial.println("Yo1");
//Serial.println();
// initialize values
RadVals[5] = 0;
CondVals[5] = 0;
AuxVals[5] = 0;
//read sensor value and set upper limit cap
int i = 0;
do {
// Find 5 data points
RadVals[i] = analogRead(RadPin);
CondVals[i] = analogRead(CondPin);
AuxVals[i] = analogRead(AuxPin);
//Serial.print("Rad pin input stored = "); Serial.println(RadVals[i]);
//Serial.print("Cond pin input stored = "); Serial.println(CondVals[i]);
//Serial.print("Aux pin input stored = "); Serial.println(AuxVals[i]);
//Serial.println(i);
//Serial.println("Yo2");
//Serial.println();
//Serial.print("Rad pin input before sum = "); Serial.println(RadVals[5]);
//Serial.println("Yo25");
//Serial.println();
// sum all 5 data points
RadVals[5] = RadVals[5] + RadVals[i];
CondVals[5] = CondVals[5] + CondVals[i];
AuxVals[5] = AuxVals[5] + AuxVals[i];
//Serial.print("Rad pin input sum = "); Serial.println(RadVals[5]);
//Serial.print("Cond pin input sum = "); Serial.println(CondVals[5]);
//Serial.print("Aux pin input sum = "); Serial.println(AuxVals[5]);
//Serial.println(i);
//Serial.println("Yo3");
//Serial.println();
i = i + 1;
} while (i < 5);
// Find Average of 5 data points
RadVals[5] = RadVals[5] / 5;
CondVals[5] = CondVals[5] / 5;
AuxVals[5] = AuxVals[5] / 5;
//Serial.print("Rad pin input Average = "); Serial.println(RadVals[5]);
//Serial.print("Cond pin input Average = "); Serial.println(CondVals[5]);
//Serial.print("Aux pin input Average = "); Serial.println(AuxVals[5]);
//Serial.println(i);
//Serial.println("Yo4");
//Serial.println();
if (RadVals[5] < Rad20) RadSpeed = 10;
if (RadVals[5] < Rad30 and RadVals[5] >= Rad20) RadSpeed = 20;
if (RadVals[5] < Rad40 and RadVals[5] >= Rad30) RadSpeed = 30;
if (RadVals[5] < Rad50 and RadVals[5] >= Rad40) RadSpeed = 40;
if (RadVals[5] < Rad60 and RadVals[5] >= Rad50) RadSpeed = 50;
if (RadVals[5] < Rad70 and RadVals[5] >= Rad60) RadSpeed = 60;
if (RadVals[5] < Rad80 and RadVals[5] >= Rad70) RadSpeed = 70;
if (RadVals[5] < Rad90 and RadVals[5] >= Rad80) RadSpeed = 80;
if (RadVals[5] >= Rad90) RadSpeed = 90;
if (CondVals[5] < Cnd20) CondSpeed = 10;
if (CondVals[5] < Cnd30 and CondVals[5] >= Cnd20) CondSpeed = 20;
if (CondVals[5] < Cnd40 and CondVals[5] >= Cnd30) CondSpeed = 30;
if (CondVals[5] < Cnd50 and CondVals[5] >= Cnd40) CondSpeed = 40;
if (CondVals[5] < Cnd60 and CondVals[5] >= Cnd50) CondSpeed = 50;
if (CondVals[5] < Cnd70 and CondVals[5] >= Cnd60) CondSpeed = 60;
if (CondVals[5] < Cnd80 and CondVals[5] >= Cnd70) CondSpeed = 70;
if (CondVals[5] < Cnd90 and CondVals[5] >= Cnd80) CondSpeed = 80;
if (CondVals[5] >= Cnd90) CondSpeed = 90;
if (AuxVals[5] < Aux20) AuxSpeed = 10;
if (AuxVals[5] < Aux30 and AuxVals[5] >= Aux20) AuxSpeed = 20;
if (AuxVals[5] < Aux40 and AuxVals[5] >= Aux30) AuxSpeed = 30;
if (AuxVals[5] < Aux50 and AuxVals[5] >= Aux40) AuxSpeed = 40;
if (AuxVals[5] < Aux60 and AuxVals[5] >= Aux50) AuxSpeed = 50;
if (AuxVals[5] < Aux70 and AuxVals[5] >= Aux60) AuxSpeed = 60;
if (AuxVals[5] < Aux80 and AuxVals[5] >= Aux70) AuxSpeed = 70;
if (AuxVals[5] < Aux90 and AuxVals[5] >= Aux80) AuxSpeed = 80;
if (AuxVals[5] >= Aux90) AuxSpeed = 90;
FanSpeed = max(RadSpeed, CondSpeed); // This is the duty Cycle
currentMillis = millis();
//if ((currentMillis - nextMillis) >= 0) {
if ((currentMillis - previousMillis) >= interval) {
//Serial.print("Current Millis = "); Serial.println(currentMillis);
//Serial.print("Next Millis = "); Serial.println(nextMillis);
//Serial.print("Previous Millis = "); Serial.println(previousMillis);
//Serial.print("interval = "); Serial.println(interval);
previousMillis = currentMillis;
if (FanState == LOW) {
FanState = HIGH;
interval = FanSpeed*period/100;
//Serial.print("interval high = "); Serial.println(interval);
} else {
FanState = LOW;
interval = period - (FanSpeed*period/100);
//Serial.print("Interval Low = "); Serial.println(interval);
}
//Serial.println();
// Serial.println();Serial.println();Serial.println();
//nextMillis += interval; //schedule the next fan cycle;
//Serial.print("Next Millis = "); Serial.println(nextMillis);
digitalWrite(FanPin, FanState);
digitalWrite(LedPin, FanState);
//Serial.print("Rad pin input Average = "); Serial.println(RadVals[5]);
//Serial.print("Cond pin input Average = "); Serial.println(CondVals[5]);
//Serial.print("Aux pin input Average = "); Serial.println(AuxVals[5]);
//Serial.print("Fan Speed = "); Serial.println(FanSpeed);
//Serial.println("Yo5");
//Serial.println();Serial.println();Serial.println();Serial.println();
}
}
When I had the problem was when I had all the Serial print statements nu-commented. They took so long to execute that the time between pulses exceeded 0.1 sec. With all those statements removed it works fine. To date I have tested it with various resistors in place of the thermisters to simulate temperature set points. I have also now installed it in the car and its working but I can only do limited testing on the car as the temperatures are too cold. However it does come on to low speed at the prescribed minimum temperature and also comes on at the prescribed condenser temperatures. I do believe that I could put in some code to only reset the duty cycle every 15 seconds or so. I will have to experiment. In that time I may be able to do other things.
Just got back from vacation and I see my 555 timer chips arrived. This will be one of the first circuits I will be trying out. My intention is to replace the 220Ω resistor and LED with the Arduino Nano 33 BLE. The max output of my particular 555 is 10ma so it may not run the Nano directly.
One question I have is that in the accompanying schematic S1 is described as a momentary switch. In my application I would like S1 to be the vehicles ignition switch and be on for many hours. If that's a problem, might there be a way of generating a pulse to act as a momentary switch with the ignition key on. So far all of the examples I have found use S1 as a momentary switch but I have found nothing to say you cant just apply voltage for as long as you want.
Show me your circuit and maybe I can comment. Edit - oh, I see, you want to power the Nano from the 555 output. How much current does the Nano draw? Does it have power consuming peripherals attached to it? Compare that with the output current spec of the 555 from its data sheet.
I think the 555 output does not swing "rail to rail"... meaning it might not supply a full 5V.
JP3 has 3.3V outputs to 3 thermisters. But the R3, R4 and R5, companion resistors have been changed to 220Ω. 3.3KΩ and 220Ω respectively, to be more compatible with the thermisters chosen.
On the C1, C2 and C3, I'm not really a person who understands how they work any more that they smooth out the voltage. I originally didn't have them but they were suggested by another user on this sight. They do go to ground through a resistor on one side. The system works very well the way they are but it also works very well with no caps installed at all. So my understanding is if I do install this system in a noisy environment they will become necessary, but until I do, I have no way to evaluate the performance of the caps. Therefore if this is incorrect let me know how to fix it. This project will require a new PCB board so its a clean pallet.