I have a project where I would like to put the Arduino Nano 33 BLE to sleep and then wake it up when needed.. The first couple of lines in the loop section are where I would like to wake up the BLE and put it to sleep. I have found a few threads on this but nothing I can comprehend. Any help would be apriciated.
// 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 /////////////////////////////////////////////////////////////////
// constants thet are desirable to adjust during debugging.
const bool SerialStatus = true; // Set to true to hold serial printing until the serial printer is started. Set to false to release hold for stand alone use
const bool WDTStatus = false; // Set to true to activate the Watch Dog Timmer, Set to false to deactivate for debugging
const unsigned long WDT = 30; // Watch Dog Timer max time seconds This must be greater than the time requird to complete a cycle
// Constant for voltage sensing
const unsigned long Resistor1 = 33000L; // Voltage divider resistor #1
const unsigned long Resistor2 = 3300L; // Voltage divider resistor #2
const float BoardV = 3.3; // Board operating voltage
const float VMult = BoardV*((Resistor1 + Resistor2)/Resistor2)/1023L; // Voltage multiplier to get voltage from analogread pin "VsnPin"
const float EngineOnVoltage = 13.2; // Voltage at which the engine is considered to be running
const float KeyOnVoltage = 12; // Voltage at which the key is considered to be on
const long PostRunInterval = 30; // Time the fan will run after engine shut down
// Constanst for program control
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
// Constants for Arduino board configuration
const int VsnPin = A0; // Circuite 15 Voltage level sensing pin
const int RadPin = A1; // Radiator Input Thermister
const int CndPin = A2; // Condenser Input Thermister
const int AuxPin = A3; // Auxilary Input Not used at this time
const int FanPin = D9; // Set Fan pin
const int LED1Pin = D4; // Set Cooling Fan LED
const int LED2Pin = D3; // Set Condenser Fan LED
const int LED3Pin = D2; // Set Aux Fan FED
/*
// 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
*/
// 10 bit temperature equivolents for radiator sensor Delphi 12146312
const int Rad0 = 1015; // - 20°C equivolent Sensor assumed open.
const int Rad20 = 579; //85C
const int Rad30 = 557; //88C
const int Rad40 = 534; //91C
const int Rad50 = 511; //94C
const int Rad60 = 487; //97C
const int Rad70 = 463; //100C
const int Rad80 = 439; //103C
const int Rad90 = 415; //106C
const int Rad100 = 355; //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 = 1004; //-30C Sensor Test point
const int Cnd20 = 632; //40C
const int Cnd30 = 583; //45C
const int Cnd40 = 534; //50C
const int Cnd50 = 486; //55C
const int Cnd60 = 440; //60C
const int Cnd70 = 396; //65C
const int Cnd80 = 355; //70C
const int Cnd90 = 317; //75C
const int Cnd100 = 174; //100C Sensor Test Point
// 10 bit temperature equivolents for temp sensor Delphi 25036751
const int Aux0 = 1015; //-20C Sensor Test Point
const int Aux20 = 571; //85C
const int Aux30 = 549; //88C
const int Aux40 = 527; //91C
const int Aux50 = 504; //94C
const int Aux60 = 480; //97C
const int Aux70 = 456; //100C
const int Aux80 = 432; //103C
const int Aux90 = 409; //106C
const int Aux100 = 290; //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 ///////////////////////////////////////////////////////////////////
bool EngineRunningStatus = false; // Initialize engine running as off
bool Keyon = false; // Initialize key position as off
bool ShutDown = false; // Initilize shutdown event an false
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 DutyCycle = 10; // Set fan to 10% PWM = Fan off
int FanSpeed = 0; // Fan speed is 0 with 10% PWM, Fan speed = 100% with 0% PWM
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("53436b3f-5f91-474b-963e-8b09b170c670"); //*** 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("0407dd37-ae29-4ec7-ab40-a83898d610df", // standard 128-bit characteristic UUID *******************************
BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic AuxLevelChar("ad43db8f-e3e6-4025-b745-43f2100f27e1", // standard 128-bit characteristic UUID *******************************
BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic FanSpeedChar("8ed03f79-29c0-46d5-a2ca-bfddd629347e", // 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);
Serial.println();
}
////////////////////////////////////////////////////////////////////////////////////
void setup()
{
// put your setup code here, to run once:
pinMode(VsnPin, INPUT);
pinMode(RadPin, INPUT);
pinMode(CndPin, INPUT);
pinMode(AuxPin, INPUT);
pinMode(LED1Pin, OUTPUT);
pinMode(LED2Pin, OUTPUT);
pinMode(LED3Pin, OUTPUT);
pinMode(FanPin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
if (SerialStatus) // Set the SerialStatus bool variable in the main body as required for stand alone use or debugging
{
Serial.begin(115200);
while(!Serial);
}
//Configure WDT.
if (WDTStatus) // Set the WDTStatus booleen variable in the main body as required to turn on or off the 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.print(F("\nStarting Car_Fan_Control using ")); Serial.println(BOARD_NAME);
Serial.println(NRF52_MBED_SLOW_PWM_VERSION);
Serial.println();
Serial.print("Resistor 1 = "); Serial.println(Resistor1);
Serial.print("Resistor 2 = "); Serial.println(Resistor2);
Serial.print("BoardV = "); Serial.println(BoardV);
Serial.print("VMult = "); Serial.println(VMult, 6);
Serial.println();
delay(200);
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); Serial.println();
}
else Serial.println(F("Can't set ITimer. Select another freq. or timer")); Serial.println();
channelNum = ISR_PWM.setPWM(PWM_Pin, frequency, DutyCycle); // During setup DutyCycle will be set to initialized value of 10 = off.
ReadAveragSensorsData(); // Read all the sensors and find the averages
// CalcDutyCycle(); // Call the CalcDutyCycle routine moved to loop
StartUpBlink(); // Call the blink sensor StartUpBlink subroutine to test all sensors
SetUpBLE(); // Call the SetUpBLE routine
Serial.println("Setup Complete *************************************************************"); Serial.println();
}
////////////////////////////////////////////////////////////////////////////////////
void loop()
{
if (VMult*analogRead(VsnPin) > EngineOnVoltage)
{
// Wake Nano 33 BLE
}
if (RunFan() == false)
{
//Put Nano 33 BLE to sleep
}
if (RunFan() == true) // Run the fan if apropriate
{
// 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) )
{
LED_status = !LED_status;
digitalWrite(LED_BUILTIN, LED_status);
UpdateTemperatures();
ReadAveragSensorsData(); // Read all the sensors and find the averages
CalcDutyCycle(); // 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
if (WDTStatus) 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());
PrintData(); // Print every update_timeout ms.
}
}
}
////////////////////////////////////////////////////////////////////////////////////
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.
}
////////////////////////////////////////////////////////////////////////////////////
bool RunFan()
{
float Voltage; // Voltage read on circuite 15 (Key Voltage)
static bool Running; // Engine runing status
static bool KeyOffEvent; // Used to determine whether or not the engine was tuned off
static bool RecentRunning; // Used to determin if the engine was running within a prescribed time
static unsigned long KeyOffMillis; // Time the key was sensed as being tuned off
unsigned long CurrentKeyMillis = millis(); // Current time
int Status;
Voltage = VMult*analogRead(VsnPin); // Get the circuit 15 voltage
if (Voltage < EngineOnVoltage && Running == true)
{
KeyOffEvent = true;
KeyOffMillis = millis();
}
else
{
KeyOffEvent = false;
}
if (Voltage >= EngineOnVoltage)
{
Running = true;
}
else
{
Running = false;
}
// Ckeck to see if key was tuned off recently
if (CurrentKeyMillis - KeyOffMillis < PostRunInterval*1000)
{
RecentRunning = true;
}
else
{
RecentRunning = false;
}
Serial.print("KeyOffMillis = "); Serial.print(KeyOffMillis);Serial.println();
Serial.print("Voltage = "); Serial.print(Voltage);Serial.println();
Serial.print("Running = "); Serial.print(Running);Serial.println();
Serial.print("KeyOffEvent = "); Serial.print(KeyOffEvent);Serial.println();
Serial.print("RecentRunning = "); Serial.print(RecentRunning);Serial.println();
Serial.print("KeyOffMillis = "); Serial.print(KeyOffMillis);Serial.println();
Serial.print("CurrentKeyMillis = "); Serial.print(CurrentKeyMillis);Serial.println();
Serial.print("CurrentKeyMillis - KeyOffMillis = "); Serial.print(CurrentKeyMillis - KeyOffMillis);Serial.println();
Serial.print("PostRunInterval = "); Serial.print(PostRunInterval*1000);Serial.println();
if (Running == true || RecentRunning == true)
{
Status = 1;
}
else
{
Status = 0;
}
Serial.print("Status = "); Serial.println(Status); Serial.println();
Serial.println();
if (Running == true || RecentRunning == true)
{
return true;
}
else
{
return false;
}
}
////////////////////////////////////////////////////////////////////////////////////
void CalcDutyCycle() // 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 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){
DutyCycle = 0; // Emergency mode rad too hot or shorted sensor = 100, sensor open = 0
}
else {
DutyCycle = max(RadSpeed, CndSpeed); // find the highest
DutyCycle = max(DutyCycle, AuxSpeed); // This is the duty Cycle
}
FanSpeed = DutyCycle;
if (DutyCycle == 0){
FanSpeed = 100;
}
PWM_LOGWARN1("Fan Speed = ", FanSpeed);
//write the PWM value to the pwm output pin
PWM_LOGWARN5("Freq = ", frequency, ", DutyCycle % = ", DutyCycle, ", Pin = ", FanPin);
if (!ISR_PWM.modifyPWMChannel(channelNum, PWM_Pin, frequency, DutyCycle))
{
Serial.print(F("modifyPWMChannel error"));
}
}
////////////////////////////////////////////////////////////////////////////////////
void StartUpBlink() // Blink LEDs at startup to test sensors are in range
{
digitalWrite(LED1Pin, HIGH); // turn the LED on
digitalWrite(LED2Pin, HIGH); // turn the LED on
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
Serial.print("StartUpBlink Complete");Serial.println();Serial.println();
}
////////////////////////////////////////////////////////////////////////////////////
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("Testing 123"); //******************************************************************************
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...");Serial.println();
}
////////////////////////////////////////////////////////////////////////////////////////
void UpdateTemperatures()
{
// Update and Print the calculated temperatures used for the BLE Characteristics
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 Fan Speed characteristics
Serial.print("Rad Temp is now: "); Serial.println(RadTemp);
Serial.print("Cnd Temp is now: "); Serial.println(CndTemp);
Serial.print("Aux Temp is now: "); Serial.println(AuxTemp);
Serial.print("Fan Speed is now: "); Serial.println(FanSpeed);Serial.println();
}
////////////////////////////////////////////////////////////////////////////////////////////////
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 = -43.43635166;
double AuxCoeff1 = 3.117548E+00;
double AuxCoeff2 = -2.416554E-02;
double AuxCoeff3 = 8.431310E-05;
double AuxCoeff4 = -1.486206E-07;
double AuxCoeff5 = 1.304135E-10;
double AuxCoeff6 = -4.532547E-14;
*/
double RadCoeff0 = 1.660314E+03;
double RadCoeff1 = -1.669192E+01;
double RadCoeff2 = 7.538496E-02;
double RadCoeff3 = -1.809468E-04;
double RadCoeff4 = 2.411013E-07;
double RadCoeff5 = -1.684504E-10;
double RadCoeff6 = 4.789740E-14;
double CndCoeff0 = 1.656447E+02;
double CndCoeff1 = -5.855249E-01;
double CndCoeff2 = 1.648293E-03;
double CndCoeff3 = -3.088415E-06;
double CndCoeff4 = 3.244812E-09;
double CndCoeff5 = -1.670822E-12;
double CndCoeff6 = 2.576671E-16;
double AuxCoeff0 = 4.949081E+02;
double AuxCoeff1 = -3.724091E+00;
double AuxCoeff2 = 1.595315E-02;
double AuxCoeff3 = -3.767238E-05;
double AuxCoeff4 = 4.990923E-08;
double AuxCoeff5 = -3.498639E-11;
double AuxCoeff6 = 1.000633E-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;
}