Bu layihə demək olar ki, ən çox ehtiyac duyulan mövzudur. Çox zaman biz bənzər layihələri internetdə görürük və təkrar edirik. Layihəmizi digər bilgi resurslarından fərqləndirən məqam Arduinonun yaddaşından istifadə edərək son tempraturu yadda saxlamaq funksyasıdır.
Layihəmizdə nə edəcəyimizin qısa xülasəsi:
İstənilən bir fanı təyin etdiyimiz istilik dərəcəsində işə salmaq;
LCD ekranda monitorinq, tempraturu təyin etmək və fanın sürətinin ayarlanması;
LCD ekranda menyudan fan üçün enkoder vasitəsi ilə tempratur, sürət, dayanma və başlama ayarlarını etmək.
İstifadə edəcəyimiz vəsaitlər:
- Arduino UNO
- 4.7K rezistor
- Fan(istənilən)
- IRF520 modulu
- Bredboard
- Bağlantı kabelləri
- DS18B20 tempratur sensoru
İndi isə layihənin sxemi ilə tanış olaq
Controller olaraq Arduino UNO istifadə edilməlidir.
#include <Wire.h>
#include <PID_v1.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
byte _d18x2x1Addr[8]={0x28, 0x20, 0x2A, 0x7, 0xD6, 0x1, 0x3C, 0x7A};
double _PID_1_Out=0.0;
double _PID_1_SP=0.0;
double _PID_1_In=0.0;
double _PID_1_Ki=0.0;
double _PID_1_Kp=0.0;
double _PID_1_Kd=0.0;
PID _PID_1(&_PID_1_In, &_PID_1_Out, &_PID_1_SP, 0, 0, 0, REVERSE);
LiquidCrystal_I2C _lcd1(0x27, 16, 2);
int _dispTempLength1=0;
boolean _isNeedClearDisp1;
OneWire _ow10(10);
bool DT_65759081_1;
bool CLK_65759081_1;
bool En_65759081_1;
bool Up_65759081_1;
bool Down_65759081_1;
byte New_65759081_1=0;
long EncData_65759081_1=0;
byte EncState_65759081_1=0;
byte ps_65759081_1=0;
byte ms_65759081_1=0;
bool DT_65759081_2;
bool CLK_65759081_2;
bool En_65759081_2;
bool Up_65759081_2;
bool Down_65759081_2;
byte New_65759081_2=0;
long EncData_65759081_2=0;
byte EncState_65759081_2=0;
byte ps_65759081_2=0;
byte ms_65759081_2=0;
const int _menuParametrsArray[] PROGMEM = {1, 4, 3, 0, 0, 0, 0, 0, 2, 4, 3, 0, 2, 4, 2, 0, 0, 0, 0, 0, 1, 4, 2, 0, 3, 4, 1, 0, 0, 0, 0, 0, 1, 4, 1, 0, 4, 4, 4, 0, 0, 0, 0, 0, 1, 4, 4, 0, 5, 4, 5, 0, 0, 0, 0, 0, 1, 4, 5, 0};
int _menuValueArray_int[5];
const int _menuConstantValuesArray_int[] PROGMEM = {100, 1};
const char _flprogMenuNameString1[] PROGMEM = "Kp";
const char _flprogMenuNameString2[] PROGMEM = "Time";
const char _flprogMenuNameString3[] PROGMEM = "TEMP";
const char _flprogMenuNameString4[] PROGMEM = "Ki";
const char _flprogMenuNameString5[] PROGMEM = "Kd";
const char* const _flprogMenuStringsArray[] PROGMEM = { _flprogMenuNameString1, _flprogMenuNameString2, _flprogMenuNameString3, _flprogMenuNameString4, _flprogMenuNameString5};
struct _menuItemStricture
{
int startInArrayIndex;
}
;
struct _menuMainStricture
{
int startIndex;
int stopIndex;
bool isSwitchMenuAroundRing;
_menuItemStricture currentItem;
}
;
_menuItemStricture _MenuItems[5];
_menuMainStricture _MainMenus[1];
int _disp2oldLength = 0;
bool _bounseInputD2S = 0;
bool _bounseInputD2O = 0;
unsigned long _bounseInputD2P = 0UL;
int _disp3oldLength = 0;
bool _trgt2 = 0;
bool _trgt2I = 0;
int _disp4oldLength = 0;
int _disp1oldLength = 0;
String _MenuBlock_216651450_MNO;
String _MenuBlock_216651450_VNO;
bool _MenuBlock_216651450_OEIS = 0;
bool _MenuBlock_216651450_OMUIS = 0;
bool _MenuBlock_216651450_OMDIS = 0;
bool _MenuBlock_216651450_OVUIS = 0;
bool _MenuBlock_216651450_OVDIS = 0;
unsigned long _d18x2x1Tti = 0UL;
float _d18x2x1O = 0.00;
bool _tempVariable_bool;
int _tempVariable_int;
float _tempVariable_float;
void setup()
{
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT);
pinMode(4, INPUT);
Wire.begin();
delay(10);
if(((readByteFromEEPROM(0, 0, 0x0))) != 189)
{
(updateByteToEEPROM(0, 0, 0x0, (189)));
(updateIntegerToEEPROM(1, 0, 0x0, (0)));
(updateIntegerToEEPROM(3, 0, 0x0, (0)));
(updateIntegerToEEPROM(5, 0, 0x0, (0)));
(updateIntegerToEEPROM(7, 0, 0x0, (0)));
(updateIntegerToEEPROM(9, 0, 0x0, (0)));
}
_lcd1.init();
_lcd1.backlight();
_bounseInputD2O = digitalRead(2);
_MenuItems[0].startInArrayIndex = 0;
_MenuItems[1].startInArrayIndex = 12;
_MenuItems[2].startInArrayIndex = 24;
_MenuItems[3].startInArrayIndex = 36;
_MenuItems[4].startInArrayIndex = 48;
_MainMenus[0].startIndex = 1;
_MainMenus[0].isSwitchMenuAroundRing = 1;
_MainMenus[0].stopIndex = 5;
_MainMenus[0].currentItem = _MenuItems[0];
_menuValueArray_int[0] = (readIntegerFromEEPROM(1, 0, 0x0));
_menuValueArray_int[1] = (readIntegerFromEEPROM(3, 0, 0x0));
_menuValueArray_int[2] = (readIntegerFromEEPROM(5, 0, 0x0));
_menuValueArray_int[3] = (readIntegerFromEEPROM(7, 0, 0x0));
_menuValueArray_int[4] = (readIntegerFromEEPROM(9, 0, 0x0));
_PID_1.SetOutputLimits(0, 255);
_PID_1.SetMode(AUTOMATIC);
}
void loop()
{
if (_isNeedClearDisp1)
{
_lcd1.clear();
_isNeedClearDisp1= 0;
}
bool _bounceInputTmpD2 = (digitalRead (2));
if (_bounseInputD2S)
{
if (millis() >= (_bounseInputD2P + 40))
{
_bounseInputD2O= _bounceInputTmpD2;
_bounseInputD2S=0;
}
}
else
{
if (_bounceInputTmpD2 != _bounseInputD2O)
{
_bounseInputD2S=1;
_bounseInputD2P = millis();
}
}
if (1)
{
_dispTempLength1 = (String("AZERCHIP")).length();
if (_disp4oldLength > _dispTempLength1)
{
_isNeedClearDisp1 = 1;
}
_disp4oldLength = _dispTempLength1;
_lcd1.setCursor(8, 1);
_lcd1.print(String("AZERCHIP"));
}
else
{
if (_disp4oldLength > 0)
{
_isNeedClearDisp1 = 1;
_disp4oldLength = 0;
}
}
if(_isTimer(_d18x2x1Tti, 1000))
{
_d18x2x1Tti = millis();
_tempVariable_float = _readDS18_ow10(_d18x2x1Addr, 0);
if (_tempVariable_float < 500)
{
_d18x2x1O = _tempVariable_float;
}
}
if (1)
{
_dispTempLength1 = (((_floatToStringWitRaz((_d18x2x1O),2)))).length();
if (_disp3oldLength > _dispTempLength1)
{
_isNeedClearDisp1 = 1;
}
_disp3oldLength = _dispTempLength1;
_lcd1.setCursor(11, 0);
_lcd1.print(((_floatToStringWitRaz((_d18x2x1O),2))));
}
else
{
if (_disp3oldLength > 0)
{
_isNeedClearDisp1 = 1;
_disp3oldLength = 0;
}
}
_tempVariable_int = (_menuValueArray_int[1]);
_PID_1.SetSampleTime(_tempVariable_int);
_PID_1_Kd = (_menuValueArray_int[4]);
_PID_1_Kp = (_menuValueArray_int[0]);
_PID_1_Ki = (_menuValueArray_int[3]);
_PID_1.SetTunings(_PID_1_Kp, _PID_1_Ki, _PID_1_Kd);
_PID_1_In = (_d18x2x1O);
_PID_1_SP = (_menuValueArray_int[2]);
_PID_1.Compute();
analogWrite(6, _PID_1_Out);
bool _tmp2 = !(_bounseInputD2O);
if (_tmp2)
{
if (! _trgt2I) _trgt2 = ! _trgt2;
}
_trgt2I = _tmp2;
DT_65759081_2 = (digitalRead (3));
CLK_65759081_2 = (digitalRead (4));
En_65759081_2 = !(_trgt2);
Up_65759081_2 =0;
Down_65759081_2 =0;
if(En_65759081_2)
{
bitWrite(New_65759081_2, 0, DT_65759081_2);
bitWrite(New_65759081_2, 1, CLK_65759081_2);
switch(EncState_65759081_2)
{
case 2:
{
if(New_65759081_2 == 3) plus_65759081_2();
if(New_65759081_2 == 0) minus_65759081_2();
break;
}
case 0:
{
if(New_65759081_2 == 2) plus_65759081_2();
if(New_65759081_2 == 1) minus_65759081_2();
break;
}
case 1:
{
if(New_65759081_2 == 0) plus_65759081_2();
if(New_65759081_2 == 3) minus_65759081_2();
break;
}
case 3:
{
if(New_65759081_2 == 1) plus_65759081_2();
if(New_65759081_2 == 2) minus_65759081_2();
break;
}
}
EncState_65759081_2 = New_65759081_2;
// Записываем новое значение
}
DT_65759081_1 = (digitalRead (3));
CLK_65759081_1 = (digitalRead (4));
En_65759081_1 = _trgt2;
Up_65759081_1 =0;
Down_65759081_1 =0;
if(En_65759081_1)
{
bitWrite(New_65759081_1, 0, DT_65759081_1);
bitWrite(New_65759081_1, 1, CLK_65759081_1);
switch(EncState_65759081_1)
{
case 2:
{
if(New_65759081_1 == 3) plus_65759081_1();
if(New_65759081_1 == 0) minus_65759081_1();
break;
}
case 0:
{
if(New_65759081_1 == 2) plus_65759081_1();
if(New_65759081_1 == 1) minus_65759081_1();
break;
}
case 1:
{
if(New_65759081_1 == 0) plus_65759081_1();
if(New_65759081_1 == 3) minus_65759081_1();
break;
}
case 3:
{
if(New_65759081_1 == 1) plus_65759081_1();
if(New_65759081_1 == 2) minus_65759081_1();
break;
}
}
EncState_65759081_1 = New_65759081_1;
// Записываем новое значение
}
if (1)
{
_tempVariable_bool = 1;
if (! _MenuBlock_216651450_OEIS)
{
_MenuBlock_216651450_OEIS = 1;
}
_tempVariable_int = pgm_read_byte(&_menuParametrsArray[((_MainMenus[0].currentItem).startInArrayIndex)+10]);
_MenuBlock_216651450_MNO = _readStringFromProgmem ((char*)pgm_read_word(&(_flprogMenuStringsArray[_tempVariable_int - 1])));
_MenuBlock_216651450_VNO = _menuOutputValueString (0);
}
else
{
_tempVariable_bool = 0;
if (_MenuBlock_216651450_OEIS)
{
_MenuBlock_216651450_OEIS = 0;
_menuUpdateToEEpromItems();
}
_MenuBlock_216651450_MNO = "";
_MenuBlock_216651450_VNO = "";
}
if(Up_65759081_2)
{
if (! _MenuBlock_216651450_OMUIS)
{
_MenuBlock_216651450_OMUIS = 1;
if(_tempVariable_bool)
{
_menuUpEvents(0);
_menuUpdateToEEpromItems();
}
}
}
else
{
_MenuBlock_216651450_OMUIS = 0;
}
if(Down_65759081_2)
{
if (! _MenuBlock_216651450_OMDIS)
{
_MenuBlock_216651450_OMDIS = 1;
if(_tempVariable_bool)
{
_menuDownEvents(0);
_menuUpdateToEEpromItems();
}
}
}
else
{
_MenuBlock_216651450_OMDIS = 0;
}
if(Up_65759081_1)
{
if (! _MenuBlock_216651450_OVUIS)
{
_MenuBlock_216651450_OVUIS = 1;
if(_tempVariable_bool)
{
_valueUpEvents(0);
}
}
}
else
{
_MenuBlock_216651450_OVUIS = 0;
}
if(Down_65759081_1)
{
if (! _MenuBlock_216651450_OVDIS)
{
_MenuBlock_216651450_OVDIS = 1;
if(_tempVariable_bool)
{
_valueDownEvents(0);
}
}
}
else
{
_MenuBlock_216651450_OVDIS = 0;
}
if (1)
{
_dispTempLength1 = ((_MenuBlock_216651450_VNO)).length();
if (_disp2oldLength > _dispTempLength1)
{
_isNeedClearDisp1 = 1;
}
_disp2oldLength = _dispTempLength1;
_lcd1.setCursor(0, 1);
_lcd1.print((_MenuBlock_216651450_VNO));
}
else
{
if (_disp2oldLength > 0)
{
_isNeedClearDisp1 = 1;
_disp2oldLength = 0;
}
}
if (1)
{
_dispTempLength1 = ((_MenuBlock_216651450_MNO)).length();
if (_disp1oldLength > _dispTempLength1)
{
_isNeedClearDisp1 = 1;
}
_disp1oldLength = _dispTempLength1;
_lcd1.setCursor(0, 0);
_lcd1.print((_MenuBlock_216651450_MNO));
}
else
{
if (_disp1oldLength > 0)
{
_isNeedClearDisp1 = 1;
_disp1oldLength = 0;
}
}
}
String _floatToStringWitRaz(float value, int raz)
{
return String(value,raz);
}
bool _isTimer(unsigned long startTime, unsigned long period)
{
unsigned long currentTime;
currentTime = millis();
if (currentTime>= startTime)
{
return (currentTime>=(startTime + period));
}
else
{
return (currentTime >=(4294967295-startTime+period));
}
}
String _readStringFromProgmem (char *string)
{
String result = String("");
while (pgm_read_byte(string)!='\0')
{
result=result+ char(pgm_read_byte(string));
string++;
}
return result;
}
void _menuUpEvents (int menuIndex)
{
int tempIndex = pgm_read_byte(&_menuParametrsArray[((_MainMenus[menuIndex]).currentItem).startInArrayIndex]);
int parIndex = pgm_read_byte(&_menuParametrsArray[ (((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+5]);
int parentStartIndex;
int parentStopIndex;
if (parIndex == 0)
{
parentStartIndex = (_MainMenus[menuIndex]).startIndex;
parentStopIndex =(_MainMenus[menuIndex]).stopIndex;
}
else
{
parentStartIndex = pgm_read_byte(&_menuParametrsArray[((_MenuItems[parIndex - 1]).startInArrayIndex)+3]);
parentStopIndex = pgm_read_byte(&_menuParametrsArray[((_MenuItems[parIndex-1]).startInArrayIndex)+4]);
}
if (tempIndex == parentStartIndex)
{
if((_MainMenus[menuIndex]).isSwitchMenuAroundRing)
{
(_MainMenus[menuIndex]).currentItem = _MenuItems[parentStopIndex -1];
return;
}
else
{
return;
}
}
(_MainMenus[menuIndex]).currentItem = _MenuItems[tempIndex - 2];
return;
}
void _menuDownEvents (int menuIndex)
{
int tempIndex = pgm_read_byte(&_menuParametrsArray[((_MainMenus[menuIndex]).currentItem).startInArrayIndex]);
int parIndex = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+5]);
int parentStartIndex;
int parentStopIndex;
if (parIndex == 0)
{
parentStartIndex = (_MainMenus[menuIndex]).startIndex;
parentStopIndex =(_MainMenus[menuIndex]).stopIndex;
}
else
{
parentStartIndex = pgm_read_byte(&_menuParametrsArray[((_MenuItems[parIndex-1]).startInArrayIndex)+3]);
parentStopIndex = pgm_read_byte(&_menuParametrsArray[((_MenuItems[parIndex-1]).startInArrayIndex)+4]);
}
if (tempIndex == parentStopIndex)
{
if((_MainMenus[menuIndex]).isSwitchMenuAroundRing)
{
(_MainMenus[menuIndex]).currentItem = _MenuItems[parentStartIndex -1];
return;
}
else
{
return;
}
}
(_MainMenus[menuIndex]).currentItem = _MenuItems[tempIndex];
return;
}
void _valueUpEvents (int menuIndex)
{
int valIndex = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+2]);
int itemType = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+1]);
int indexMax = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+6]);
int indexStep = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+8]);
if (itemType == 4)
{
_menuValueArray_int[valIndex -1] = _menuValueArray_int[valIndex -1] + (pgm_read_word(&_menuConstantValuesArray_int[indexStep -1]));
}
}
void _valueDownEvents (int menuIndex)
{
int valIndex = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+2]);
int itemType = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+1]);
int indexMin = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+7]);
int indexStep = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+8]);
if (itemType == 4)
{
_menuValueArray_int[valIndex - 1] = _menuValueArray_int[valIndex - 1] - (pgm_read_word(&_menuConstantValuesArray_int[indexStep - 1]));
}
}
String _menuOutputValueString (int menuIndex)
{
int itemType = pgm_read_byte(&_menuParametrsArray[ (((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+1]);
int valIndex = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+2]);
int indexMin = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+7]);
int indexMax = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+6]);
if(valIndex == 0)
{
return "";
}
int convFormat = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+9]);
if(itemType == 4)
{
return _convertNamber(itemType, convFormat, valIndex, indexMax, indexMin);
}
return "";
}
void _menuUpdateToEEpromItems()
{
(updateIntegerToEEPROM(1, 0, 0x0, ((_menuValueArray_int[0]))));
(updateIntegerToEEPROM(3, 0, 0x0, ((_menuValueArray_int[1]))));
(updateIntegerToEEPROM(5, 0, 0x0, ((_menuValueArray_int[2]))));
(updateIntegerToEEPROM(7, 0, 0x0, ((_menuValueArray_int[3]))));
(updateIntegerToEEPROM(9, 0, 0x0, ((_menuValueArray_int[4]))));
}
String _convertNamber(int itemType, int convFormat, int valIndex, int indexMax, int indexMin)
{
if (itemType== 4)
{
if (convFormat == 4)
{
return String((_menuValueArray_int[valIndex - 1 ]),DEC);
}
if (convFormat == 5)
{
return String((_menuValueArray_int[valIndex - 1]),HEX);
}
if (convFormat == 6)
{
return String((_menuValueArray_int[valIndex -1]),BIN);
}
}
return "";
}
float _convertDS18x2xData(byte type_s, byte data[12])
{
int16_t raw = (data[1] << 8) | data[0];
if (type_s)
{
raw = raw << 3;
if (data[7] == 0x10)
{
raw = (raw & 0xFFF0) + 12 - data[6];
}
}
else
{
byte cfg = (data[4] & 0x60);
if (cfg == 0x00)raw = raw & ~7;
else if(cfg == 0x20)raw = raw & ~3;
else if(cfg == 0x40) raw = raw & ~1;
}
return (float)raw / 16.0;
}
float _readDS18_ow10(byte addr[8], byte type_s)
{
byte data[12];
byte i;
_ow10.reset();
_ow10.select(addr);
_ow10.write(0xBE);
for (i = 0; i < 9; i++)
{
data[i] = _ow10.read();
}
_ow10.reset();
_ow10.select(addr);
_ow10.write(0x44);
if (_ow10.crc8(data, 8) != data[8])
{
return 501;
}
return _convertDS18x2xData(type_s, data);
}
void plus_65759081_1()
{
ps_65759081_1++;
if(ps_65759081_1>= 1)
{
Up_65759081_1 =1;
ps_65759081_1=0;
}
}
void minus_65759081_1()
{
ms_65759081_1++;
if(ms_65759081_1>= 1)
{
Down_65759081_1 =1;
ms_65759081_1=0;
}
}
void plus_65759081_2()
{
ps_65759081_2++;
if(ps_65759081_2>= 1)
{
Up_65759081_2 =1;
ps_65759081_2=0;
}
}
void minus_65759081_2()
{
ms_65759081_2++;
if(ms_65759081_2>= 1)
{
Down_65759081_2 =1;
ms_65759081_2=0;
}
}
byte readByteFromEEPROM(int addres, byte bitAddres, byte chipAddres)
{
return EEPROM.read(addres);
}
void updateByteToEEPROM(int addres, byte bitAddres, byte chipAddres, byte value)
{
return EEPROM.update(addres, value);
}
int readIntegerFromEEPROM(int addres, byte bitAddres, byte chipAddres)
{
byte hight = readByteFromEEPROM(addres, bitAddres, chipAddres);
byte low = readByteFromEEPROM((addres+1), bitAddres, chipAddres);
return word(hight, low);
}
void updateIntegerToEEPROM(int addres, byte bitAddres, byte chipAddres, int value)
{
updateByteToEEPROM(addres, bitAddres, chipAddres, highByte(value));
updateByteToEEPROM((addres+1), bitAddres, chipAddres, lowByte(value));
}