#include "AiEsp32RotaryEncoder.h"
#include "Arduino.h"
#include
#include
#include // Core graphics library
#include
#include
#include "EEPROMAnything.h"
#define TFT_SDA 23
#define TFT_SCLK 18
#define TFT_CS 5 // gpio0 D3
#define TFT_RST 4
// in which case, set this #define pin to -1!
#define TFT_DC 2 // GPIO15 D2
#define TFT_BL 25 // Display backlight pin
// one hour 3600000
#define ST7735_TFTHEIGHT 128
#define ST7735_TFTWIDTH 128
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_SDA, TFT_SCLK, TFT_RST);
//Temperature sensor pins
#define sensorPin1 33
#define sensorPin2 32
// Rotary Encoder Inputs
#define ROTARY_ENCODER_A_PIN 35
#define ROTARY_ENCODER_B_PIN 34
#define ROTARY_ENCODER_BUTTON_PIN 27
//mounting the wires for the Encoder Button, make sure to notice which one is GRND, as it may also share with the Encoder A and B Pins.
#define ROTARY_ENCODER_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
#define FanRelay 26
#define key1 13 //connect wire 1 to pin 10
#define key2 12 //connect wire 2 to pin 11
#define key3 14 //connect wire 3 to pin 12
#define buzzer 15
//depending on your encoder - try 1,2 or 4 to get expected behaviour
//#define ROTARY_ENCODER_STEPS 1
//#define ROTARY_ENCODER_STEPS 2
#define ROTARY_ENCODER_STEPS 4
//instead of changing here, rather change numbers above
AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
static unsigned long lastTimeIncPressed;
byte cnt;
int key1S;
int key2S;
int key3S;
byte Point;
byte TmpMax;
byte IncTmpMax;
byte SW;
byte Session = 0;
byte SessionEvent;
int count1 = 8;
int count2 = 8;
int raw1 = 0;
int raw2 = 0;
//Not tested with Pin 15 yet - is the only normal pin left though.
//const int buzzer = 15; //buzzer pin
//EEPROM
int TempMax = 1;
//some colors
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define PURPLE 0xF81F
#define MAGENTA 0xFFE0
#define CYAN 0x07FF
#define WHITE 0xFFFF
void rotary_onButtonClick()
{
static unsigned long lastTimePressed = 0;
//ignore multiple press in that time milliseconds
if (millis() - lastTimePressed < 500)
{
return;
}
lastTimePressed = millis();
Serial.print("button pressed ");
// Serial.print(millis());
// Serial.println(" milliseconds after restart");
TmpMax = IncTmpMax;
Serial.print("Updating TmpMax to "); Serial.println(TmpMax);
EEPROM_update(TempMax, TmpMax);
tft.setTextSize(2);
tft.setCursor(2, 90);
tft.setTextColor(RED, BLACK);
tft.print("Store ");// tft.print(IncTmpMax);
delay(1000);
tft.fillRect(0, 90, 100, 20, BLACK);
}
void rotary_loop()
{
//dont print anything unless value changed
if (rotaryEncoder.encoderChanged())
{
Serial.print("Value: ");
Serial.println(rotaryEncoder.readEncoder());
IncTmpMax = rotaryEncoder.readEncoder();
if (IncTmpMax < 25 || IncTmpMax > 70)
{
IncTmpMax = 25;
}
tft.setTextSize(2);
tft.setCursor(2, 90);
tft.setTextColor(CYAN, BLACK);
tft.print("SET "); tft.print(IncTmpMax); tft.print(" ");
cnt = 1;
}
if (rotaryEncoder.isEncoderButtonClicked() && (IncTmpMax != TmpMax))
{
rotary_onButtonClick();
}
}
void IRAM_ATTR readEncoderISR()
{
rotaryEncoder.readEncoder_ISR();
}
void setup() {
Serial.begin(115200);
//we must initialize rotary encoder
rotaryEncoder.begin();
rotaryEncoder.setup(readEncoderISR);
//set boundaries and if values should cycle or not
//in this example we will set possible values between 0 and 1000;
bool circleValues = false;
rotaryEncoder.setBoundaries(25, 70, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
/*Rotary acceleration introduced 25.2.2021.
in case range to select is huge, for example - select a value between 0 and 1000 and we want 785
without accelerateion you need long time to get to that number
Using acceleration, faster you turn, faster will the value raise.
For fine tuning slow down.
*/
//rotaryEncoder.disableAcceleration(); //acceleration is now enabled by default - disable if you dont need it
rotaryEncoder.setAcceleration(1); //or set the value - larger number = more accelearation; 0 or 1 means disabled acceleration
EEPROM.begin(96);
Wire.begin();
// Check for backlight pin if not connected to VCC
#ifndef TFT_BL
Serial.println("No TFT backlight pin defined");
#else
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
#endif
pinMode(key1, INPUT_PULLUP);// set pin as input
pinMode(key2, INPUT_PULLUP);// set pin as input
pinMode(key3, INPUT_PULLUP);// set pin as input
pinMode(FanRelay, OUTPUT);
pinMode(buzzer, OUTPUT);
digitalWrite (FanRelay, LOW);
// Set encoder pins as inputs
pinMode(ROTARY_ENCODER_BUTTON_PIN, INPUT_PULLUP);
tft.initR(INITR_GREENTAB); // initialize a ST7735S chip, green tab
tft.fillScreen(BLACK);
tft.setRotation(1);
tft.setTextWrap(false);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(1);
tft.setCursor(10, 120);
tft.print("Outlet 24V. 5A.");
EEPROM_readAnything(TempMax, TmpMax);
if (TmpMax < 25 || TmpMax > 70)
{
TmpMax = 25;
EEPROM_update(TempMax, TmpMax);
}
IncTmpMax = TmpMax;
//for the touchpad 3 buttons, not in use.
// if (Point != 1 || Point != 2 || Point != 3)
// {
// Point = 3;
// }
digitalWrite (FanRelay, HIGH); //when turned on at first, spin up and then down.
delay(4000);
digitalWrite (FanRelay, LOW);
}
void EEPROM_update(int address, int8_t value)
{
if (EEPROM.read(address) != value)
{
EEPROM.write(address, value);
EEPROM.commit();
}
return;
}
void loop() {
rotary_loop();
DisTemperature();
if (cnt == 1)
{
DFR();
}
//Btns();// if there are 3 buttons attached
}
void DisTemperature()
{
/* ************ Temperature ************ */
MakeTempAverage();
unsigned long TTnow = millis();
static unsigned long nextTempTime = 0;
static unsigned long nextTTempTime = 0;
//float tmpraw, tempaverage, and average
if (TTnow > nextTTempTime) {
{
nextTTempTime = TTnow + 1;
}
if (TTnow > nextTempTime)
{
nextTempTime = TTnow + (4020);//time to make an average temp.
raw1 = raw1 / count1;
raw2 = raw2 / count2;
// Convert the voltage into the temperature in degree Celsius:
float temperature1 = (1.44 * raw1 * 100.0) / 1024 + 1;
float temperature2 = (1.435 * raw2 * 100.0) / 1024 + 1;
// Print the temperature in the Serial Monitor:
Serial.print("temp1 "); Serial.print(temperature1, 1);
Serial.print(" \xC2\xB0"); // shows degree symbol for serial monitor. Symbol will not show for the display.
Serial.print("C");
Serial.print(" temp2 "); Serial.print(temperature2, 1);
Serial.print(" \xC2\xB0"); // shows degree symbol
Serial.println("C");
// Make some readout on the tft display
tft.setTextSize(2);
tft.setCursor(2, 0);
tft.setTextColor(CYAN, BLACK);
tft.print("Net");
tft.setCursor(85, 0);
tft.print("DC");
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(2);
tft.setCursor(2, 21);
tft.print(temperature1, 1);
tft.setCursor(85, 21);
tft.print(temperature2, 1);
tft.setTextSize(2);
tft.setCursor(2, 44);
tft.print("Thold ");
tft.setCursor(85, 44);
tft.print(TmpMax);// The Max temperature to make the Fan speed up
if (((temperature1 >= TmpMax) && digitalRead(FanRelay) == LOW) || (temperature2 >= TmpMax) && digitalRead(FanRelay) == LOW)
{
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(2);
tft.setCursor(2, 66);
tft.print("Speed ");
//tft.setCursor(85, 66);
tft.setTextColor(RED, BLACK);
tft.print("Fast");
digitalWrite (FanRelay, HIGH);
Session = 1;
SessionEvent = 35;//amount of degrees to cool down
}
if (Session == 1 && (temperature1 <= SessionEvent) && (temperature2 <= SessionEvent) && digitalRead(FanRelay) == HIGH)
{
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(2);
tft.setCursor(2, 66);
tft.print("Speed ");
//tft.setCursor(85, 66);
tft.setTextColor(GREEN, BLACK);
tft.print("Slow");
digitalWrite (FanRelay, LOW);
Session = 0;
}
TTnow = 0;
}
}
}/* End Temperature */
//void Beep()
//{
// digitalWrite(buzzer, HIGH);
// delay(300);
// digitalWrite(buzzer, LOW);
//}
void MakeTempAverage()
{
unsigned long MTMPAnow = millis();
static unsigned long MTMPAnextTempTime = 0;
static unsigned long MTMPAnextTTempTime = 0;
if (MTMPAnow > MTMPAnextTTempTime) {
{
MTMPAnextTTempTime = MTMPAnow + 1;
}
if (MTMPAnow > MTMPAnextTempTime)
{
MTMPAnextTempTime = (MTMPAnow + 500);
{
count1 = 8;
count2 = 8;
raw1 = 0;
raw2 = 0;
for (int i = 0; i < count1; i++) raw1 += analogRead(sensorPin1);
for (int i = 0; i < count2; i++) raw2 += analogRead(sensorPin2);
}
MTMPAnow = 0;
}
}
}
void DFR()
{
unsigned long DFRnow = millis();
static unsigned long DFRnextTempTime = 0;
static unsigned long DFRnextTTempTime = 0;
if (DFRnow > DFRnextTTempTime) {
{
DFRnextTTempTime = DFRnow + 1;
}
if (DFRnow > DFRnextTempTime)
{
DFRnextTempTime = (DFRnow + 10000);
{
tft.fillRect(0, 90, 100, 20, BLACK);//clear the SET TmpMax text afterwards
cnt = 0;
}
DFRnow = 0;
}
}
}
//void Btns()
//{
// unsigned long BTNnow = millis();
// static unsigned long BTNnextTempTime = 0;
// static unsigned long BTNnextTTempTime = 0;
// if (BTNnow > BTNnextTTempTime) {
// {
// BTNnextTTempTime = BTNnow + 1;
// }
// if (BTNnow > BTNnextTempTime)
// {
// BTNnextTempTime = BTNnow + (300);
// Touchpad with 3 buttons
// key1S = digitalRead(key1);// read if key1 is pressed
// key2S = digitalRead(key2);// read if key2 is pressed
// key3S = digitalRead(key3);// read if key3 is pressed
//
// if (!key1S) {
// Serial.println("key 1 is pressed");
// Point = 1;
// }
// if (!key2S) {
// Serial.println("key 2 is pressed");
// Point = 2;
//
// }
// if (!key3S) {
// Serial.println("key 3 is pressed");
// Point = 3;
// // digitalWrite (FanRelay, LOW);
// }
// BTNnow = 0;
// }
// }
//}
regards
Fungreenfox
I see English is your second language so I hope I am clear. It helps if you leave out useless and null statements to reduce the code volume (like beep and empty #include's) also if you can eliminate any code not directly involved in the perceived problem that also helps to reduce code volume. One last thing, statements like
if (beta == gamma){
doSomething;
}
Occupy much less code space when written as
if (beta == gamma) doSomething;
3 lines down to 1
Hope this is of some assistance.
Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting
Is this for your paranormal research?
Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting
here are two LM35 temp sensors for arduino esp32 script, placedover the two heatsinks on a power supplier.
Experience is what you get when you don't get what you want.
@zander I have built some ghostscanners, but this one is for a power supplier like the example, but with an esp32 also.
The case is designed by me, and printed at my 3dprinter.
A little video showing the case.
regards
Fungreenfox
@zander Outcommented lines are not seen by the compiled script; only by the editor.
Don't worry about the english 🙂
regards
Fungreenfox
@fungreenfox The point is to reduce what we have to look at. The less the better. Until the volume is cut by 2/3 I will wait.
Arduino says and I agree, in general, the const keyword is preferred for defining constants and should be used instead of #define
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon
My experience hours are >75,000 and I stopped counting in 2004.
Major Languages - 360 Macro Assembler, Intel Assembler, PLI/1, Pascal, C plus numerous job control and scripting
I'm finding your work a little hard to interpret. As an example, consider your module for MakeTempAverage() which seems germane to the problem.
void MakeTempAverage() { unsigned long MTMPAnow = millis(); static unsigned long MTMPAnextTempTime = 0; static unsigned long MTMPAnextTTempTime = 0; if (MTMPAnow > MTMPAnextTTempTime) { { MTMPAnextTTempTime = MTMPAnow + 1; } if (MTMPAnow > MTMPAnextTempTime) { MTMPAnextTempTime = (MTMPAnow + 500); { count1 = 8; count2 = 8; raw1 = 0; raw2 = 0; for (int i = 0; i < count1; i++) raw1 += analogRead(sensorPin1); for (int i = 0; i < count2; i++) raw2 += analogRead(sensorPin2); } MTMPAnow = 0; } } }
You have placed brace brackets around the line "MTMPAnextTTempTime = MTMPAnow + 1;". These seem to do nothing, so I'm curious why you have enclosed it with brackets and indented the line.
Similarly, you surround the code "count1 = 8 ... analogRead(sensorPin2);" and indent it as well, again apparently, for no benefit.
What am I missing here ?
Experience is what you get when you don't get what you want.
I'm finding your work a little hard to interpret. As an example, consider your module for MakeTempAverage() which seems germane to the problem.
void MakeTempAverage() { unsigned long MTMPAnow = millis(); static unsigned long MTMPAnextTempTime = 0; static unsigned long MTMPAnextTTempTime = 0; if (MTMPAnow > MTMPAnextTTempTime) { { MTMPAnextTTempTime = MTMPAnow + 1; } if (MTMPAnow > MTMPAnextTempTime) { MTMPAnextTempTime = (MTMPAnow + 500); { count1 = 8; count2 = 8; raw1 = 0; raw2 = 0; for (int i = 0; i < count1; i++) raw1 += analogRead(sensorPin1); for (int i = 0; i < count2; i++) raw2 += analogRead(sensorPin2); } MTMPAnow = 0; } } }
You have placed brace brackets around the line "MTMPAnextTTempTime = MTMPAnow + 1;". These seem to do nothing, so I'm curious why you have enclosed it with brackets and indented the line.
Similarly, you surround the code "count1 = 8 ... analogRead(sensorPin2);" and indent it as well, again apparently, for no benefit.
What am I missing here ?
Normally, its not needed to place brackets around that line, if there is only one. This is for a making it more easy to discover what the if is there for. Brackets there, may be set or left out, if wanted and shoould not have any influence on this.
At the two for - lines for analogread sensorpin 1 and 2, this is for making the average.
-I really do not know, what You are missing. 🙂
regards
Fungreenfox
if you're using an ESP, are you running the LM35 from 3.3V or 5V ? You'll need the 5V and add a capacitor for extra stability.
Experience is what you get when you don't get what you want.
Hi @fungreenfox,
Sorry, I am not clear what these words in your opening message actually mean ... could you clarify please?
The average of temperature in Celcius, is taken by 8 readings over 4 seconds, and it looks stabile.When mounted, there are "spikes" from 25 up to 70 celcius, ......
The first sentence says the readings are "stable" ... suggesting you seeing steady temperature readings.
But the second sentence says you are seeing "spikes" ... from 25 up to 75 Celcius.
These two descriptions appear to contradict each other.
The only clue as to why they might be different is the second sentence starts "When mounted" ... which you will be able to visualise and understand, but as I cannot see your equipment, I can only guess what you mean.
------------
- Are you saying that the readings change from "stable" to "spiking" when you "mount" something?
- If so, what and where are you "mounting".
----------------------------------
Please accept my apologies in advance if I have misunderstood your message ... I have a long history of asking many stupid questions... 🙄
Best wishes, Dave
@will 5V, and a capacitor at 220uf 10V. - it doesn't change amount or size of spikes.
regards
Fungreenfox
Maybe this will help ...
https://bestengineeringprojects.com/lm35-how-to-get-stable-temperature-reading/
Experience is what you get when you don't get what you want.
Normally, its not needed to place brackets around that line, if there is only one. This is for a making it more easy to discover what the if is there for. Brackets there, may be set or left out, if wanted and shoould not have any influence on this.
Strictly speaking, it's probably not a big deal in this particular case, but this is not the default case for every situation, thus better not to include such brackets in general code at all.
Why?
Because, those brackets introduce an ANAONYMOUS SCOPE, and can catch you out in situations you may not be aware of!
They can (and are), also used for beneficial purposes in program design.
Best to avoid adding them if you don't fully understand their function / value.
Cheers