I've got a perplexing problem and I hope someone here has an answer for me. I have an if statement at the start of the main loop that works one time and then seems to skip the condition thereafter. What complicates this is that it is on an ATTiny 85 and I had no way of debugging with console, that is until I did some digging and found I could use the Uno serial connection. So I adjusted my program to use TinyDebugSerial and got a weird result. As you can see from the code below, if I run the program with the first Serial statement commented out, it fails to function properly. If, however, I leave the statement in, the program runs as it should. The way the program should work is that the analog read and write statements should run constantly unless the fan rpm drops below the threshold and then the output should drop to zero and the led will flash indicating the error. Because the checkFan function needs 1 second to get a reading from the rpmPin, I didn't want this constantly interfering with the analog read/write so I set it to sample every 5 seconds (i'm probably going to increase this time, if I can get the program working right). The fastPWM stuff is so that I can get a PWM frequency of about 4KHz.
I figured there was a timing issue somewhere so I tried adding a small delay at both the start and the end of the main loop, but I can only get the program to work if the initial serial statement is in there (the one that says "here"). With that statement in, I get the other serial data every 5 seconds just like I planed it. As an added bonus, the "flashLED" function does not work right either. The LED only flashes once and not twice as expected (more of an annoyance than a problem right meow).
I am using the internal 8MHz oscillator. I commented out the fastPWM stuff when I started trying to troubleshoot, thinking maybe that was causing an issue but to no avail. I have also tried using a fresh micro as well with the same results. I have commented out one of my outputs as I needed that pin for the serial debugging. Just ignore the other commented stuff as this is stuff I use in the actual application (to keep up with PWM timings and such....yet another headache I have had to battle through).
Please forgive the terrible coding that I'm sure some of you seasoned programmers are gonna find. I'm learning from multiple sources all using different practices and methods of doing things. I try my best to understand the code snippets I find on the internet before deploying them in my projects. I hope I was descriptive enough.
#include <TinyDebugSerial.h>
TinyDebugSerial Serial = TinyDebugSerial();
const int pwmPin = 1;
const int ledGrn = 0;
//const int ledRed = 3;
const int potPin = A2;
//const int rpmPin = 2;
int inVal = 0;
int NbTopsFan; int Calc;
//The pin location of the sensor
int hallsensor = 2; typedef struct{
//Defines the structure for multiple fans and their dividers
char fantype;
unsigned int fandiv; }fanspec;
//Definitions of the fans
//This is the varible used to select the fan and it's divider,
//set 1 for unipole hall effect sensor and 2 for bipole hall
//effect sensor
fanspec fanspace[3]={{0,1},{1,2},{2,8}}; char fan = 1;
// when using millis, 1 sec = 7812
//unsigned long interval = 31248; //this is 4s (7812 x 4)
unsigned long interval = 5000;
unsigned long curTime;
volatile bool cooling = true;
void setup() {
// set the micro to use fastPWM
// TCCR0A = 2<<COM0A0 | 2<<COM0B0 | 3<<WGM00;
// TCCR0B = 0<<WGM02 | 1<<CS01;
// TCCR1 = 0<<PWM1A | 0<<COM1A0 | 1<<CS10;
// GTCCR = 1<<PWM1B | 2<<COM1B0;
pinMode(pwmPin, OUTPUT);
analogWrite(pwmPin, 0);
pinMode(ledGrn, OUTPUT);
// pinMode(ledRed, OUTPUT);
// pinMode(rpmPin, INPUT);
pinMode(hallsensor, INPUT);
attachInterrupt(0, rpm, RISING);
digitalWrite(ledGrn, HIGH); // turn on green LED for control OK
// digitalWrite(ledRed, LOW);
//delay(3125); //500ms
Serial.begin(9600);
delay(20); //500ms
}
void loop() {
// Serial.println("here");
delay(20);
if (cooling) {
inVal = analogRead(potPin);
analogWrite(pwmPin, inVal/4);
if (millis() >= interval) {
// interval = millis() + 31248;
interval = (millis() + 5000UL);
Serial.print(millis());
Serial.print(" mills and ");
Serial.print(interval);
Serial.println(" interval");
// if (interval >= 4294951665) { // check to see if interval is close to millis overflow
// interval = 31248; //reset interval if it is above millis overflow less 2 secs
// interval = 4000UL; //reset interval if it is above millis overflow less 4 secs
// }
checkFan();
}
} else {
analogWrite(pwmPin, 0);
flashLED();
checkFan();
}
//delay(20);
}
void rpm() {
NbTopsFan++;
}
void checkFan() {
NbTopsFan = 0;
sei();
// delay(7812);
delay(1000);
cli();
Calc = ((NbTopsFan * 60)/fanspace[fan].fandiv);
if (Calc >= 6500) {
cooling = true; // turn on green side of LED
grnLED();
} else {
cooling = false;
digitalWrite(ledGrn, LOW);
//redLED();
}
}
void flashLED() {
digitalWrite(ledGrn, LOW);
delay(400);
digitalWrite(ledGrn, HIGH);
delay(400);
digitalWrite(ledGrn, LOW);
delay(1000);
}
void grnLED() {
digitalWrite(ledGrn, HIGH);
// digitalWrite(ledRed, LOW);
}
//void redLED() {
// digitalWrite(ledRed, HIGH);
// digitalWrite(ledGrn, LOW);
//}