Thank you khoig.
That was very successful. I had to make a few changes to get it to run my fan but very minimal.
I changed
PWM_LOGINFO3("Rad(", index, ") input = ", RadVals[index]);
PWM_LOGINFO3("Cond(", index, ") input = ", RadVals[index]);
PWM_LOGINFO3("Aux(", index, ") input = ", RadVals[index]);
to:
PWM_LOGINFO3("Rad(", index, ") input = ", RadVals[index]);
PWM_LOGINFO3("Cond(", index, ") input = ", CondVals[index]);
PWM_LOGINFO3("Aux(", index, ") input = ", AuxVals[index]);
I also had to comment out the
while (!Serial);
Otherwise it would not run my fan unless connected to a USB cable.
[code]
#if !( ARDUINO_ARCH_NRF52840 && TARGET_NAME == ARDUINO_NANO33BLE )
#error This code is designed to run on nRF52-based Nano-33-BLE boards using mbed-RTOS platform! Please check your Tools->Board setting.
#endif
#define _PWM_LOGLEVEL_ 2
#define USING_MICROS_RESOLUTION true //false
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "nRF52_MBED_Slow_PWM.h" // https://github.com/khoih-prog/nRF52_MBED_Slow_PWM
#define HW_TIMER_INTERVAL_US 20L
uint32_t startMicros = 0;
// For mbed nRF52, you can only select NRF52 Hardware Timer NRF_TIMER_3-NRF_TIMER_4 (3 to 4)
// If you select the already-used NRF_TIMER_0-2, it'll be auto modified to use NRF_TIMER_3
// Init NRF52 timer NRF_TIMER3
NRF52_MBED_Timer ITimer(NRF_TIMER_3);
// Init nRF52_Slow_PWM, each can service 16 different ISR-based PWM channels
NRF52_MBED_Slow_PWM ISR_PWM;
///////////////////////////////////////////////////////////////////
int RadPin = A0;
int CondPin = A1;
int AuxPin = A2;
#define NUMBER_OF_SAMPLES 5
int RadVals [NUMBER_OF_SAMPLES] = {0, 0, 0, 0, 0};
int CondVals[NUMBER_OF_SAMPLES] = {0, 0, 0, 0, 0};
int AuxVals [NUMBER_OF_SAMPLES] = {0, 0, 0, 0, 0};
int RadValAvg = 0;
int CondValAvg = 0;
int AuxValAvg = 0;
#define FAKE_TESTING false
#if FAKE_TESTING
// Make fake temp higher to speed-up the fan in lab test
// 10 bit temperature equivalents for radiator sensor
int Rad20 = 444; //85C
int Rad30 = 484; //90C
int Rad40 = 524; //95C
int Rad50 = 562; //100C
int Rad60 = 599; //105C
int Rad70 = 635; //110C
int Rad80 = 668; //115C
int Rad90 = 699; //120C
#else
int Rad20 = 444; //85C
int Rad30 = 484; //90C
int Rad40 = 524; //95C
int Rad50 = 562; //100C
int Rad60 = 599; //105C
int Rad70 = 635; //110C
int Rad80 = 668; //115C
int Rad90 = 699; //120C
#endif
// 10 bit temperature equivolents for condenser sensor
int Cnd20 = 391; //40C
int Cnd30 = 440; //45C
int Cnd40 = 489; //50C
int Cnd50 = 537; //55C
int Cnd60 = 583; //60C
int Cnd70 = 627; //65C
int Cnd80 = 668; //70C
int Cnd90 = 706; //75C
int Aux20 = 0;
int Aux30 = 0;
int Aux40 = 0;
int Aux50 = 0;
int Aux60 = 0;
int Aux70 = 0;
int Aux80 = 0;
int Aux90 = 0;
int RadSpeed = 10;
int CondSpeed = 10;
int AuxSpeed = 10;
float FanSpeed = 10; // Set fan to 10% PWM = off
int FanPin = 9; // Set Fan pin
//////////////////////////////////////////////////////
void TimerHandler()
{
ISR_PWM.run();
}
//////////////////////////////////////////////////////
// You can assign pins here. Be careful to select good pin to use or crash
// Use LED_BUILTIN to test LED blinking
//uint32_t PWM_Pin = LED_BUILTIN;
uint32_t PWM_Pin = FanPin;
// Channel number used to identify associated channel
int channelNum;
////////////////////////////////////////////////
//////////////////////////////////////////////////////
float frequency = 10.0f;
void printData(const int& index = 0)
{
PWM_LOGINFO3("Rad(", index, ") input = ", RadVals[index]);
PWM_LOGINFO3("Cond(", index, ") input = ", CondVals[index]);
PWM_LOGINFO3("Aux(", index, ") input = ", AuxVals[index]);
}
void printAvg()
{
PWM_LOGWARN1("RadAvg = ", RadValAvg);
PWM_LOGWARN1("CondAvg = ", CondValAvg);
PWM_LOGWARN1("AuxAvg = ", AuxValAvg);
}
void readAnalogData(const int& index)
{
RadVals[index] = analogRead(RadPin);
CondVals[index] = analogRead(CondPin);
AuxVals[index] = analogRead(AuxPin);
// sum all 5 data points
RadValAvg += RadVals [index];
CondValAvg+= CondVals[index];
AuxValAvg += AuxVals [index];
}
void updateCheck()
{
int index = 0;
RadValAvg = 0;
CondValAvg = 0;
AuxValAvg = 0;
do
{
// Read 5 data points
readAnalogData(index);
printData(index);
index = index + 1;
} while (index < NUMBER_OF_SAMPLES);
// Find Average of 5 data points
RadValAvg = RadValAvg / NUMBER_OF_SAMPLES;
CondValAvg = CondValAvg / NUMBER_OF_SAMPLES;
AuxValAvg = AuxValAvg / NUMBER_OF_SAMPLES;
printAvg();
if (RadValAvg < Rad20) RadSpeed = 10;
if (RadValAvg < Rad30 and RadValAvg >= Rad20) RadSpeed = 20;
if (RadValAvg < Rad40 and RadValAvg >= Rad30) RadSpeed = 30;
if (RadValAvg < Rad50 and RadValAvg >= Rad40) RadSpeed = 40;
if (RadValAvg < Rad60 and RadValAvg >= Rad50) RadSpeed = 50;
if (RadValAvg < Rad70 and RadValAvg >= Rad60) RadSpeed = 60;
if (RadValAvg < Rad80 and RadValAvg >= Rad70) RadSpeed = 70;
if (RadValAvg < Rad90 and RadValAvg >= Rad80) RadSpeed = 80;
if (RadValAvg >= Rad90) RadSpeed = 90;
if (CondValAvg < Cnd20) CondSpeed = 10;
if (CondValAvg < Cnd30 and CondValAvg >= Cnd20) CondSpeed = 20;
if (CondValAvg < Cnd40 and CondValAvg >= Cnd30) CondSpeed = 30;
if (CondValAvg < Cnd50 and CondValAvg >= Cnd40) CondSpeed = 40;
if (CondValAvg < Cnd60 and CondValAvg >= Cnd50) CondSpeed = 50;
if (CondValAvg < Cnd70 and CondValAvg >= Cnd60) CondSpeed = 60;
if (CondValAvg < Cnd80 and CondValAvg >= Cnd70) CondSpeed = 70;
if (CondValAvg < Cnd90 and CondValAvg >= Cnd80) CondSpeed = 80;
if (CondValAvg >= Cnd90) CondSpeed = 90;
if (AuxValAvg < Aux20) AuxSpeed = 10;
if (AuxValAvg < Aux30 and AuxValAvg >= Aux20) AuxSpeed = 20;
if (AuxValAvg < Aux40 and AuxValAvg >= Aux30) AuxSpeed = 30;
if (AuxValAvg < Aux50 and AuxValAvg >= Aux40) AuxSpeed = 40;
if (AuxValAvg < Aux60 and AuxValAvg >= Aux50) AuxSpeed = 50;
if (AuxValAvg < Aux70 and AuxValAvg >= Aux60) AuxSpeed = 60;
if (AuxValAvg < Aux80 and AuxValAvg >= Aux70) AuxSpeed = 70;
if (AuxValAvg < Aux90 and AuxValAvg >= Aux80) AuxSpeed = 80;
if (AuxValAvg >= Aux90) AuxSpeed = 90;
// FanSpeed = max(RadSpeed, CondSpeed);
// FanSpeed = max(FanSpeed, AuxSpeed);
FanSpeed = CondSpeed;
/*
Serial.println();
Serial.print("Rad Speed = "); Serial.print(RadSpeed); Serial.println();
Serial.print("Cond Speed = "); Serial.print(CondSpeed); Serial.println();
Serial.print("Rad Speed = "); Serial.print(RadSpeed); Serial.println();
Serial.print("Fan Speed = "); Serial.print(FanSpeed); Serial.println();
Serial.println();
*/
PWM_LOGWARN1("Fan Speed = ", FanSpeed);
//write the PWM value to the pwm output pin
PWM_LOGWARN5("Freq = ", frequency, ", FanSpeed % = ", FanSpeed, ", Pin = ", FanPin);
if (!ISR_PWM.modifyPWMChannel(channelNum, PWM_Pin, frequency, FanSpeed))
{
Serial.print(F("modifyPWMChannel error"));
}
}
#define PRINT_INTERVAL 10000L
#define UPDATE_CHECK_INTERVAL_MS 1000L
void check_status()
{
static unsigned long print_timeout = 0;
static unsigned long update_timeout = 0;
static bool LED_status = HIGH;
// Print every PRINT_INTERVAL (10) seconds.
if ((millis() > print_timeout) || (print_timeout == 0))
{
printData();
print_timeout = millis() + PRINT_INTERVAL;
}
if ( (millis() > update_timeout) && (millis() > UPDATE_CHECK_INTERVAL_MS) )
{
// Blink LED
LED_status = !LED_status;
digitalWrite(LED_BUILTIN, LED_status);
updateCheck();
update_timeout = millis() + UPDATE_CHECK_INTERVAL_MS;
}
}
void setup()
{
// put your setup code here, to run once:
pinMode(RadPin, INPUT);
pinMode(FanPin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
//while (!Serial);
delay(200);
Serial.print(F("\nStarting Car_Fan_Control using ")); Serial.println(BOARD_NAME);
Serial.println(NRF52_MBED_SLOW_PWM_VERSION);
digitalWrite(LED_BUILTIN, HIGH);
// Interval in microsecs
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler))
{
startMicros = micros();
Serial.print(F("Starting ITimer OK, micros() = ")); Serial.println(startMicros);
}
else
Serial.println(F("Can't set ITimer. Select another freq. or timer"));
channelNum = ISR_PWM.setPWM(PWM_Pin, frequency, FanSpeed);
}
void loop()
{
check_status();
}
[/code]
See attached pictures of fan running at 40% duty cycle.
Uploading: P1030724.JPG...