Possibly damaged two Nano 33 BLE's trying to connect to app

Of course, all we have achieved is to send fake values :joy:

I'm concerned about the reliability of those boards. Considering their purpose, they need to be robust and reliable. You don't think you have got a bad batch?

The box for the board is probably going to need it's own cooling fan.

True but that has been the big problem. The current setup works fine without any board cooling fan. I just got back from FL with 100° F heat. The board only drives a 10ma PWM signal. No issues so far except I was limited to the Light Blue software which was very awkward to use.

OK so I am back after delivering two truckloads, 20,000 Lb of machines from NC to CT.

And guess what, the BLE that was dead when I left is now up and functioning again after a weeks rest. That's the same thing that happened in the beginning when I had three boards not working. It sort of like some capacitor on the board got charged up incorrectly and had to settle over a week. So back to having two BLE's to test with. This sort of answers the original question about damaged BLE's. Apparently there are certain thing that can be done with code to make a BLE unable to connect, but fixable when they set disconnected for a bit.

So I am having difficulty understanding the way the Fan_Control_10 works. If you could provide some explanation of whats was required to get the 4 values to show up independently that would be a big help.

Also Fan_Control_10 as well as some of the previous versions form about 6 and up will connect with LightBlue but wont display any meaningful data. I was wondering if they are doing something that is non-standard here.

So at this point Fan_Control_10 works with the fake values we have been sending it. Now for real values.

The attached code works well using LightBlue software but will need to be modified to work with Fan_Control_10. This is the software that is installed in the car now.

PWM_Fan_for_Nano_With_WDT_and_BLE.ino (22.1 KB)

A leap into the dark unknown:

Fan_Control_11.aia (216.2 KB)
FanControl11.ino (5.7 KB)

I'm away for four days, Friday-to-Monday inc, and only available sporadically between now and then.

Hi John

PWM_Fan_for_Nano_With_WDT_and_BLE.ino

I can't get that Sketch to compile!

It fails on all sorts of errors with nRF52_MBED_Slow_PWM.h and it's included files. Can you upload yours?

nRF52_MBED_Slow_PWM.h
nRF52_MBED_Slow_PWM.hpp
nRF52_MBED_Slow_PWM_Impl.h
nRF52_MBED_Slow_PWM_ISR.h
nRF52_MBED_Slow_PWM_ISR.hpp
nRF52_MBED_Slow_PWM_ISR_Impl.h
PWM_Generic_Debug.h

No problem uploading here. Did you install the "nRF52_MBED_Slow_PWM.h" library. It also has a watchdog timer that will require you to do a factory reset (double button press) on the board if it trips, as well as resting the com ports after you reset and again after you complete the upload.

// 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
#include <ArduinoBLE.h>

Fan_Control_11.aia does not show the app in the list of BLE devices.

However using FanControl11.ino with Fan_Control_10.aia works.

I can up load it, but it does not Compile. Given that the developer has archived the files, it's possible that your copy of them are in better shape.

...but it doesn't deliver the temperatures?

.....but why are you using the PWM library John?

I think you have sent me the wrong version of PWM_Fan_for_Nano_With_WDT_and_BLE.ino

.... because, even if the PWM lib was flawless, the Sketch itself has syntax errors that would prevent it from compiling.

I just loaded this one successfully, but it should be the same one I already gave you. Im posting this as text, maybe it will make a differance.

// Note this program uses a watchdog timmer.
// It is required to reset the Arduino by two presses of the reset button and setting available com ports prior to upload.
// After upload the com port needs to be reset.

// Define Global Constants /////////////////////////////////////////////////////////////////

const int RadPin = A0;                        // Radiator Input Thermister
const int CndPin = A1;                        // Condenser Input Thermister
const int AuxPin = A2;                        // Auxilary Input Not used at this time
const int FanPin = 9;                         // Set Fan pin
const int LED1Pin = 7;                        // Set Cooling Fan LED
const int LED2Pin = 6;                        // Set Condenser Fan LED
const int LED3Pin = 5;                        // Set Aux Fan FED

const unsigned long WDT = 30;                 // Watch Dog Timer max time seconds This must be greater than the time requird to complete a cycle

const int frequency = 10.0;                   // Set fan frequency
const int NumberOfSamples = 20;               // Sent number of data samples for averaging.
const int BlinkTimeOnTest  = 2000;            // Blink time on period for initial circuit test
const int BlinkTimeOn      = 500;             // Blink time on period
const int BlinkTimeOff     = 500;             // Blink time off period

// 10 bit temperature equivolents for radiator sensor Delphi 12146312
const int Rad0   = 8;      // - 20°C equivolent Sensor assumed open.
const int Rad20  = 444;    //85C
const int Rad30  = 466;    //88C
const int Rad40  = 489;    //91C
const int Rad50  = 512;    //94C
const int Rad60  = 536;    //97C
const int Rad70  = 560;    //100C
const int Rad80  = 584;    //103C
const int Rad90  = 608;    //106C
const int Rad100 = 668;    //115C This is an emergency mode either coolant is too hot or senser is shorted. Set duty cycle to 0 to activate emergency mode

// 10 bit temperature equivolents for condenser sensor Litlefuse USP7766
const int Cnd0   = 19;     //-30C Sensor Test point
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 Cnd100 = 849;    //100C Sensor Test Point

// 10 bit temperature equivolents for temp sensor Delphi 25036751
const int Aux0   = 8;      //-20C Sensor Test Point
const int Aux20  = 452;    //85C
const int Aux30  = 474;    //88C
const int Aux40  = 496;    //91C
const int Aux50  = 519;    //94C
const int Aux60  = 543;    //97C
const int Aux70  = 567;    //100C
const int Aux80  = 591;    //103C
const int Aux90  = 614;    //106C
const int Aux100 = 733;    //125C Sensor Test Point

#define _PWM_LOGLEVEL_                2
#define USING_MICROS_RESOLUTION       true    //false 
#define HW_TIMER_INTERVAL_US          20L         
#define PRINT_INTERVAL                15000L      // Interval of time ms for printing to the serial moniter
#define UPDATE_CHECK_INTERVAL_MS      15000L      // Interval of time for fan to run befor checking sensors and re adjusting fan speed

// Initialize Global Variables ///////////////////////////////////////////////////////////////////

int RadVals [NumberOfSamples + 1];
int CndVals [NumberOfSamples + 1];
int AuxVals [NumberOfSamples + 1];

int RadValAvg = 0;
int CndValAvg = 0;
int AuxValAvg = 0;

int RadSpeed = 10;
int CndSpeed = 10;
int AuxSpeed = 10;

int RadTemp;
int CndTemp;
int AuxTemp;

int FanSpeed = 10;            // Set fan to 10% PWM = off

uint32_t startMicros = 0;

// You can assign pins here. Be careful to select good pin to use or crash
uint32_t PWM_Pin    = FanPin;

// Channel number used to identify associated channel
int channelNum;

//////////////////////////////////////////////////////

#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

// 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
#include <ArduinoBLE.h>

// 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;

///////////////////////////////////////////////////////////////////////// Define the Temperature Service for BLE
BLEService TempService("10187e9f-f0c6-496c-9003-64d40d8c4b3e");        //*** BLEService Class Any Hex Name 128-bit UUID in String format *********************************************************

// Define Temperature and Fan Speed Characteristics
BLEUnsignedIntCharacteristic RadLevelChar("694d181e-4421-47f3-9653-c4d6bb295a07",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic CndLevelChar("bf9c5598-19ed-4dfb-b6fc-fe136b7210e4",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic AuxLevelChar("3b310c7c-dacf-4a27-a297-6454dd561393",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic FanSpeedChar("efb1fe61-7de4-40e6-891c-84b626081c11",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

////////////////////////////////////////////////////////////////////////////////////
void TimerHandler()
{ 
  ISR_PWM.run();
}

////////////////////////////////////////////////////////////////////////////////////
void printData(const int& index = 0)      // Subroutine to print each pin value to the serial monitor
                                          // Note this subroutine must be declared befor it is called?
{
  PWM_LOGINFO3("Rad(", index, ") input = ", RadVals[index]);
  PWM_LOGINFO3("Cnd(", index, ") input = ", CndVals[index]);
  PWM_LOGINFO3("Aux(", index, ") input = ", AuxVals[index]);
}

////////////////////////////////////////////////////////////////////////////////////
void printAvg()                           // Subroutine to print the average values to the serial monitor
                                          // Not this subroutine must be declared befor it is called?
{
  PWM_LOGWARN1("RadAvg = ", RadValAvg);
  PWM_LOGWARN1("CndAvg = ", CndValAvg);
  PWM_LOGWARN1("AuxAvg = ", AuxValAvg);
}


////////////////////////////////////////////////////////////////////////////////////
void setup() 
{
  // put your setup code here, to run once:
  pinMode(RadPin, INPUT);
  pinMode(LED1Pin, OUTPUT);
  pinMode(LED2Pin, OUTPUT);
  pinMode(LED3Pin, OUTPUT);
  pinMode(FanPin, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  //Configure WDT.
  NRF_WDT->CONFIG         = 0x01;         // Configure WDT to run when CPU is asleep
  NRF_WDT->CRV            = WDT*32769;    // CRV = WDT *(32768 + 1)
  NRF_WDT->RREN           = 0x01;         // Enable the RR[0] reload register
  NRF_WDT->TASKS_START    = 1;            // Start WDT       
    
  NRF_WDT->RR[0] = WDT_RR_RR_Reload;      // Reset WDT
  Serial.println("Watchdog iniialized and Set *************************************************************");  
                          
  Serial.begin(115200);           
  // while (!Serial);                        // Comment this out prior to installation

  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);  // During setup FanSpeed will be set to initialized value of 10 = off.
  
  ReadAveragSensorsData();          // Read all the sensors and find the averages
  CalcFanSpeed();                   // Call the CalcFanSpeed routine
  StartUpBlink();                   // Call the blink sensor StartUpBlink subroutine to test all sensors
  SetUpBLE();                       // Call the SetUpBLE routine
  
  Serial.println("Setup Complete *************************************************************"); Serial.println();
}
   
////////////////////////////////////////////////////////////////////////////////////
void loop(){

  // wait for a Bluetooth® Low Energy central
  BLEDevice central = BLE.central();

  // if a central is connected to the peripheral:
  
  static unsigned long update_timeout = 0;
  static bool LED_status = HIGH;

  // Take reading every update_timeout ms.
  if ( (millis() > update_timeout) && (millis() > UPDATE_CHECK_INTERVAL_MS) )
  {   
    printData(); // Print every update_timeout ms.
    LED_status = !LED_status;
    digitalWrite(LED_BUILTIN, LED_status);
    ReadAveragSensorsData();        // Read all the sensors and find the averages
    CalcFanSpeed();                 // Call read sensors subroutine to calculate fan speed and print values to serial moniter
    CalculateTemperatures();        // Calculate the thermister temperatures
    //BlinkSpeed();                   // Call blink test to blink out speeds  
    Serial.print("millis() = "); Serial.println(millis());
    NRF_WDT->RR[0] = WDT_RR_RR_Reload; // Reset WDT
    Serial.println("Watchdog Reset *************************************************************");  
    update_timeout = millis() + UPDATE_CHECK_INTERVAL_MS;
    
    if (central) {
      Serial.print("Connected to central: ");
      // print the central's BT address:
      Serial.println(central.address());
      // turn on the LED to indicate the connection:
      digitalWrite(LED_BUILTIN, HIGH);
      updateTemperatures();
    }
    
    // when the central disconnects, turn off the LED:
    digitalWrite(LED_BUILTIN, LOW);
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());

  }
}

////////////////////////////////////////////////////////////////////////////////////
void ReadAveragSensorsData() // Subroutine to read each pin and sum them
{
  int index = 0;

  RadValAvg = 0;
  CndValAvg = 0;
  AuxValAvg = 0;
     
  do 
  {
    // Read al data points

  RadVals[index]  = analogRead(RadPin);
  CndVals[index]  = analogRead(CndPin);
  AuxVals[index]  = analogRead(AuxPin);

  // sum all data points
  RadValAvg += RadVals [index];
  CndValAvg += CndVals[index];
  AuxValAvg += AuxVals [index];

    printData(index);               //Call the printData subroutine to print each reading to the serial monitor.

    index = index + 1;

  } while (index < NumberOfSamples);

  // Find Average of all data points
  RadValAvg  = RadValAvg  / NumberOfSamples;
  CndValAvg  = CndValAvg  / NumberOfSamples;
  AuxValAvg  = AuxValAvg  / NumberOfSamples;

  printAvg();                       //Call the printAvg function to print the average data to the serial monitor.

}

////////////////////////////////////////////////////////////////////////////////////
void CalcFanSpeed()                  // Subroutine to do 1 cycle of reading the temperature data
{

  // Find the speed levels required by each sensor Not only rad temperature can initiate emergency mode.
  if (RadValAvg < Rad0) RadSpeed = 0;           // Open sensor assumed fan will run in emergency mode at 100%
  if (RadValAvg < Rad20 and RadValAvg >= Rad0) RadSpeed = 10;   // 10% duty cycle = fan off
  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 < Rad100 and RadValAvg >= Rad90) RadSpeed = 90;
  if (RadValAvg >= Rad100) RadSpeed = 100;        // Set PWM duty cycle to 0 for emergency mode

  if (CndValAvg < Cnd20) CndSpeed = 10;   // 10% duty cycle = fan off
  if (CndValAvg < Cnd30 and CndValAvg >= Cnd20) CndSpeed = 20;
  if (CndValAvg < Cnd40 and CndValAvg >= Cnd30) CndSpeed = 30;
  if (CndValAvg < Cnd50 and CndValAvg >= Cnd40) CndSpeed = 40;
  if (CndValAvg < Cnd60 and CndValAvg >= Cnd50) CndSpeed = 50;
  if (CndValAvg >= Cnd60) CndSpeed = 60;                // Condensor is limited to 60%

  if (AuxValAvg < Aux20) AuxSpeed = 10;   // 10% duty cycle = fan off
  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;
  
  // find the sensor with the highest speed requirment or set emergency mode
  if (RadSpeed == 100|| RadSpeed == 0){   
    FanSpeed = 0;                         // Emergency mode rad too hot or shorted sensor = 100, sensor open = 0
  }
  else {
    FanSpeed = max(RadSpeed, CndSpeed); // find the highest
    FanSpeed = max(FanSpeed, AuxSpeed);  // This is the duty Cycle
  }
  
  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"));
  }
}

////////////////////////////////////////////////////////////////////////////////////
void StartUpBlink()                          // Blink LEDs at startup to test sensors are in range
{
  // Sensor one time test on startup test, Blink lights for each sensor in range.

  if (analogRead(RadPin) >= Rad0 && analogRead(RadPin) <= Rad100) {
    digitalWrite(LED1Pin, HIGH); // turn the LED on 
  }

  if (analogRead(CndPin) >= Cnd0 && analogRead(CndPin) <= Cnd100) {
    digitalWrite(LED2Pin, HIGH); // turn the LED on
  }
  
  if (analogRead(AuxPin) >= Aux0 && analogRead(RadPin) <= Rad100) {
    digitalWrite(LED3Pin, HIGH);  // turn the LED on
  }
  
  delay(BlinkTimeOnTest);       // Time to leave LEDs on
  digitalWrite(LED1Pin, LOW);   // turn the LED off 
  digitalWrite(LED2Pin, LOW);   // turn the LED off
  digitalWrite(LED3Pin, LOW);   // turn the LED off
}

////////////////////////////////////////////////////////////////////////////////////
void BlinkSpeed()                               // Blink LEDs to indicate speed called by each sensor
{
  int CountRadOn  = 0;    // Counter for number of radiator blinks on
  int CountCndOn  = 0;    // Counter for number of condenser blinks on
  int CountAuxOn  = 0;    // Counter for number of Aux blinks on

  int CountRadOff = 0;    // Counter for number of radiator blinks off
  int CountCndOff = 0;    // Counter for number of condenser blinks off
  int CountAuxOff = 0;    // Counter for number of Aux blinks off
  
  int RadBlinks   = 0;    // Initialise number of blinks based on radiator temp
  int CndBlinks   = 0;    // Initialise number of blinks based on Condenser temp
  int AuxBlinks   = 0;    // Initialise number of blinks based on Aux temp
  int MaxBlinks   = 0;    // Maximum number of blinks for all channels
  
  int index = 0;
  
  RadBlinks = RadSpeed/10;      // Number of Blinks Based on Rad Temp
  CndBlinks = CndSpeed/10;      // Number of Blinks Based on Cnd Temp
  AuxBlinks = AuxSpeed/10;      // Number of Blinks Based on Aux Temp
  MaxBlinks = max(RadBlinks, CndBlinks);
  MaxBlinks = max(MaxBlinks, AuxBlinks);    // Find the total number of blinks required
    
  do {                                      // Do the blink loop until the max number of blinks has occured.
     
      CountRadOn = CountRadOn + 1;
      CountCndOn = CountCndOn + 1;
      CountAuxOn = CountAuxOn + 1;
      if (CountRadOn <= RadBlinks) {
        digitalWrite(LED1Pin, HIGH); // turn the LED on 
      }      
      if (CountCndOn <= CndBlinks) {
        digitalWrite(LED2Pin, HIGH); // turn the LED on 
      }      
      if (CountAuxOn <= AuxBlinks) {
        digitalWrite(LED3Pin, HIGH); // turn the LED on 
      }

      delay(BlinkTimeOn);           // Time to leave LEDs on
      digitalWrite(LED1Pin, LOW);   // turn the LED off 
      digitalWrite(LED2Pin, LOW);   // turn the LED off
      digitalWrite(LED3Pin, LOW);   // turn the LED off
      delay(BlinkTimeOff);          // Time to leave LEDs on
           
    index = index + 1;
  } while (index < MaxBlinks);
}
  
////////////////////////////////////////////////////////////////////////////////////
  void SetUpBLE() {
  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");

    while (1);
  }

  /* Set a local name for the Bluetooth® Low Energy device
     This name will appear in advertising packets
     and can be used by remote devices to identify this Bluetooth® Low Energy device
     The name can be changed but maybe be truncated based on space left in advertisement packet
  */

    BLE.setLocalName("Fan Control Monitor"); //******************************************************************************
    BLE.setAdvertisedService(TempService); // add the service UUID
    TempService.addCharacteristic(RadLevelChar); // add the radiator level characteristic
    TempService.addCharacteristic(CndLevelChar); // add the condenser level characteristic
    TempService.addCharacteristic(AuxLevelChar); // add the aux level characteristic
    TempService.addCharacteristic(FanSpeedChar); // add the fan Speed characteristic
    
    BLE.addService(TempService);  // Add the Temperature service
    RadLevelChar.writeValue(0);   // set initial value for this characteristic
    CndLevelChar.writeValue(0);   // set initial value for this characteristic
    AuxLevelChar.writeValue(0);   // set initial value for this characteristic
    FanSpeedChar.writeValue(0);   // set initial value for this characteristic

  // Start advertising Bluetooth® Low Energy.  It will start continuously transmitting Bluetooth® Low Energy
  // advertising packets and will be visible to remote Bluetooth® Low Energy central devices
  // until it receives a new connection

  BLE.advertise();  // start advertising

  Serial.println("Bluetooth® device active, waiting for connections...");

  } 

////////////////////////////////////////////////////////////////////////////////////////
  void updateTemperatures() {
  // Read the current voltage level on each analog input pin.
  //   This is used here to simulate the charge level of temperaturs.

  Serial.print("Rad Level % is now: "); Serial.println(RadTemp);
  Serial.print("Cnd Level % is now: "); Serial.println(CndTemp);
  Serial.print("Aux Level % is now: "); Serial.println(AuxTemp);
  Serial.print("Fan Speed % is now: "); Serial.println(FanSpeed);

  RadLevelChar.writeValue(RadTemp);            // update the Radiator level characteristics
  CndLevelChar.writeValue(CndTemp);            // update the Condenser level characteristics
  AuxLevelChar.writeValue(AuxTemp);            // update the Aux level characteristics
  FanSpeedChar.writeValue(FanSpeed);           // update the Aux level characteristics
  
  }

 ////////////////////////////////////////////////////////////////////////////////////////////////
  void CalculateTemperatures() {
  //// Defining 6th order polynomial coefficients
  
  double RadCoeff0 = -3.191109E+01;
  double RadCoeff1 =  1.333142E+00;
  double RadCoeff2 = -9.388659E-03;
  double RadCoeff3 =  3.502677E-05;
  double RadCoeff4 = -6.643350E-08;
  double RadCoeff5 =  6.164271E-11;
  double RadCoeff6 = -2.214795E-14;

  double CndCoeff0 = -4.330212E+01;
  double CndCoeff1 =  7.697340E-01;
  double CndCoeff2 = -4.329864E-03;
  double CndCoeff3 =  1.423127E-05;
  double CndCoeff4 = -2.456664E-08;
  double CndCoeff5 =  2.111208E-11;
  double CndCoeff6 = -7.068046E-15;

  double AuxCoeff0 = -3.210410E+01;
  double AuxCoeff1 =  1.316881E+00;
  double AuxCoeff2 =  1.316881E+00;
  double AuxCoeff3 =  3.414067E-05;
  double AuxCoeff4 = -6.438080E-08;
  double AuxCoeff5 =  5.940511E-11;
  double AuxCoeff6 = -2.122449E-14;


  //Calculate temperatures
  
  RadTemp = RadCoeff0 + RadCoeff1*RadValAvg + RadCoeff2*RadValAvg*RadValAvg + RadCoeff3*RadValAvg*RadValAvg*RadValAvg + RadCoeff4*RadValAvg*RadValAvg*RadValAvg*RadValAvg + RadCoeff5*RadValAvg*RadValAvg*RadValAvg*RadValAvg*RadValAvg + RadCoeff6*RadValAvg*RadValAvg*RadValAvg*RadValAvg*RadValAvg*RadValAvg;
  CndTemp = CndCoeff0 + CndCoeff1*CndValAvg + CndCoeff2*CndValAvg*CndValAvg + CndCoeff3*CndValAvg*CndValAvg*CndValAvg + CndCoeff4*CndValAvg*CndValAvg*CndValAvg*CndValAvg + CndCoeff5*CndValAvg*CndValAvg*CndValAvg*CndValAvg*CndValAvg + CndCoeff6*CndValAvg*CndValAvg*CndValAvg*CndValAvg*CndValAvg*CndValAvg;
  AuxTemp = AuxCoeff0 + AuxCoeff1*AuxValAvg + AuxCoeff2*AuxValAvg*AuxValAvg + AuxCoeff3*AuxValAvg*AuxValAvg*AuxValAvg + AuxCoeff4*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg + AuxCoeff5*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg + AuxCoeff6*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg; 
  
  }

I have to use the PWM library to run the fan, because the fan will only accept a PWM signal of 10Hz. The lower limit without the library is somewhere over 200Hz.

That library though is intended for Projects where there is a need for several PWM components - servo/stepper driven robots, that kind of thing.

What I need from you file wise are the dependency files I listed in Post #147.

I found these files under D:......\Arduino\libraries\nRF52_MBED_Slow_PWM\src You will need to remove the .txt extension.

These were installed when I downloaded the library from

https://github.com/khoih-prog/nRF52_MBED_Slow_PWM

nRF52_MBED_Slow_PWM.h.txt (1.7 KB)
nRF52_MBED_Slow_PWM.hpp.txt (13.4 KB)
nRF52_MBED_Slow_PWM_Impl.h.txt (4.1 KB)
nRF52_MBED_Slow_PWM_ISR.h.txt (1.7 KB)
nRF52_MBED_Slow_PWM_ISR.hpp.txt (8.4 KB)
nRF52_MBED_Slow_PWM_ISR_Impl.h.txt (10.3 KB)
PWM_Generic_Debug.h.txt (6.1 KB)

1 Like

Those are the ones I need - the Lib has been archived, there is no longer a download, just read only. It is possible to copy-paste, but the latest version files seem to have been left partially edited by the Author - he made a note somewhere about another Lib but now I can't find that note.

When I first started playing with it there was no library available for low speed PWM for the Nano BLE. He had just got that one posted and for all I know, I very well may have been his first user. Maybe he found he had problems with it, but for me, with my single channel PWM application, it works just fine. He did have another Lib but it didn't work for me.

Will it work with the files I sent you.

Here's a link to the original release of the PWM library. Not it shows 2 versions, but you need the "slow" version to get down to 10Hz.

There are errors in the timer definitions.

Try compiling
PWM_Fan_for_Nano_With_WDT_and_BLE.ino

Hmmm

I don't get such errors. I see you have a later version of the Arduino IDE. I will try to upgrade to V1.8.19 and see if I get any problems.

Compiles and loads with IDE Version 1.8.19. I don't understand why you cant compile it. I assume you have the correct libraries installed?