Hi every one ;)
I want to share another project with you:
I have a home with a small garden and it need a watering system.
So I was thinking about smart system to did that but it not enough (only watering system) … I was thinking about smarter home!
Therefore, I define a project for myself that contain 4 part:
1. Vibrate Detector: if someone come it alert me (HDX) (Detect Vibrate with HDX AND Nanoframework - Hackster.io)
2. Gas detection: if gas lake in my kitchen it alert me (mq5)
3. Watering system: it give a water to garden automatically
4. Gsm system: to communicate with home from out of home (m66 r2)
Wee need some module:
Hdx sensor:
MQ5 sensor:
Water motor:
M66 r2:
Switch key:
Buzzer:
ESP32 wroom32:
I posted about hdx before so I ignore it here.
(Detect Vibrate with HDX AND Nanoframework - Hackster.io)
Mq5 is gas detection sensor. It has 4 pin: ground, Digital Pin, Analog Pin, Power
I need a buzzer to alert me if the sensor detect gas
you can use Analog output or digital output of MQ5, here I used Analog output:
you can read analog data from module with nanoframework:
AdcController adc = AdcController.GetDefault();
_m66Ver = adc.OpenChannel(_channelGasAD);
private static ADReult ReadMQGasValue()
{
Thread.Sleep(100);
return new ADReult
{
Ratio = _m66Ver.ReadRatio(),
Value = _m66Ver.ReadValue(),
};
}
To Enable Buzzer I Write This:
private static void StartWarning()
{
float dutyCycle = 1.0f;
bool goingUp = true;
_pwmPin.SetActiveDutyCyclePercentage(dutyCycle);
Thread.Sleep(200);
_pwmPin.Start();
warningIsActive = true;
while (true)
{
if (!warningIsActive)
{
break;
}
if (goingUp)
{
dutyCycle = 1.0f;
goingUp = !goingUp;
}
else
{
dutyCycle -= 0.10f;
goingUp = !goingUp;
}
Thread.Sleep(100);
_pwmPin.SetActiveDutyCyclePercentage(dutyCycle);
Thread.Sleep(100);
if (_gasDetection.Read() == GpioPinValue.High)
{
break;
}
}
Thread.Sleep(50);
_pwmPin.Stop();
}
Note: this module (buzzer) work with pwm, so you can make your sound note with that.
nanoFramework also support pwm protocol so you can control any pwm module easily
Totally I scan the gas Intensity and when that’s Intensity violation from my threshold I will start the buzzer alarm:
thMQ5Scan = new Thread(() =>
{
while (true)
{
if (!isMQ5ScanStarted)
{
break;
}
res = ReadMQGasValue();
// Debug.WriteLine($"R:{res.Ratio} V:{res.Value}");
if (res.Value > gasMaxTh && counter >= 0)
{
counter--;
}
if (res.Value < gasMaxTh && counter <= 5)
{
counter++;
}
if (counter <= 0 && !warningIsActive)
{
//active alarm
Debug.WriteLine("StartWarning!!");
Thread t = new Thread(StartWarning);
t.Start();
}
if (counter >= 5 && warningIsActive)
{
//deactive alarm
Debug.WriteLine("StopWarning!!");
StopWarning();
}
Thread.Sleep(1000);
}
});
thMQ5Scan.Start();
Water system to open and close water stream:
I schedule system to open water stream in specific times every day
For example, open water stream with low Intensity from 7 am until 8 pm every day
I did that easily with a simple timer:
_timer1 = newTimer(CheckStatus, autoEvent, 2000, 60000);
public static void CheckStatus(Object stateInfo)
{
if (_key1.Read() == GpioPinValue.High
|| _key2.Read() == GpioPinValue.High)
{
return;
}
var currentTime = GetCurrentDateTimeLocal();
if (!isWaterActive && currentTime.Hour > startHour && currentTime.Hour < endHour)
{
Thread thWater = new Thread(StartWaterMotor);
thWater.Start();
}
}
private static void StartWaterMotor()
{
try
{
Thread.Sleep(100);
isWaterActive = true;
while (true)
{
var currentTime = GetCurrentDateTimeLocal();
if (currentTime.Hour > startHour && currentTime.Hour < endHour)
{
if (!GetDeviceStatus())
{
SetDeviceStatus(true);
}
Thread.Sleep(60000);
if (_key1.Read() == GpioPinValue.High)
{
SetDeviceStatus(false);
Thread.Sleep(100);
break;
}
}
else
{
SetDeviceStatus(false);
Thread.Sleep(100);
break;
}
}
isWaterActive = false;
Thread.Sleep(200);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
isWaterActive = false;
}
}
Note: You Should Set ESP32 DateTime. with this code you can set it:
Rtc.SetSystemTime(new DateTime(2021, 9, 24, 15, 40, 10));
of course I set it with sms command!
also I added two switch key to control water motor manually.
M66 for communication. I used it in some scenarios:
1. If someone come in home it alert me
2. I can check gas Intensity from out of home
3. I can change water system schedule by SMS
4. And ……
M66 r2 work with Serial (UART). I developer two package for Nano framework:
1. Serial Helper for work with serial protocol (AP.NanoFramework.Serial/README.md at main · AlirezaP/AP.NanoFramework.Serial (github.com))
you can work with serial easily with this package:
sample code:
// COM2 in ESP32-WROVER-KIT mapped to free GPIO pins
// mind to NOT USE pins shared with other devices, like serial flash and PSRAM
// also it's MANDATORY to set pin function to the appropriate COM before instantiating it
// set GPIO functions for COM2 (this is UART1 on ESP32)
Configuration.SetPinFunction(17, DeviceFunction.COM2_TX);
Configuration.SetPinFunction(16, DeviceFunction.COM2_RX);
_gsmSerialDevice = SerialDevice.FromId("COM2");
_gsmSerialDevice.BaudRate = 9600;// 9600;
_gsmSerialDevice.Parity = SerialParity.None;
_gsmSerialDevice.StopBits = SerialStopBitCount.One;
_gsmSerialDevice.Handshake = SerialHandshake.None;
_gsmSerialDevice.DataBits = 8;
_apSerialHelper = new AP.NanoFrameWork.Serial.SerialHelper(_gsmSerialDevice);
_serialHelper.DataRecivedEventHandler += _serialHelper_DataRecivedEventHandler;
_serialHelper.WriteToSerial("some data1", "ok", true, true);
_serialHelper.WriteToSerial("some data2", "ok");
_serialHelper.WriteToSerial("some data3");
private void _serialHelper_DataRecivedEventHandler(object source, Serial.SerialHelper.MyEventArgs e)
{
string dataRecived = e.GetInfo();
Debug.WriteLine("from Event: " + dataRecived + " End event");
}
2. M66 r2 package for work with m66 (of course this depending with serial helper package)
3. (AP.NanoFrameWork.M66/README.md at master · AlirezaP/AP.NanoFrameWork.M66 (github.com))
//.................................................
// COM2 in ESP32-WROVER-KIT mapped to free GPIO pins
// mind to NOT USE pins shared with other devices, like serial flash and PSRAM
// also it's MANDATORY to set pin function to the appropriate COM before instantiating it
// set GPIO functions for COM2 (this is UART1 on ESP32)
Configuration.SetPinFunction(17, DeviceFunction.COM2_TX);
Configuration.SetPinFunction(16, DeviceFunction.COM2_RX);
_gsmSerialDevice = SerialDevice.FromId("COM2");
_gsmSerialDevice.BaudRate = 9600;// 9600;
_gsmSerialDevice.Parity = SerialParity.None;
_gsmSerialDevice.StopBits = SerialStopBitCount.One;
_gsmSerialDevice.Handshake = SerialHandshake.None;
_gsmSerialDevice.DataBits = 8;
_apSerialHelper = newAP.NanoFrameWork.Serial.SerialHelper(_gsmSerialDevice);
//_apSerialHelper.DataRecivedEventHandler += _apSerialHelper_DataRecivedEventHandler;
_m66R2 = newAP.NanoFrameWork.M66.R2(_apSerialHelper, _pinNumberGSMPowerKey);
_m66R2.SmsRecivedEventHandler += _m66R2_SmsRecivedEventHandler;
For example when some come in home the vibrate sensor trigger esp then esp send a sms to me:
hdxVibrationSensor.InvokeEvent += HdxVibrationSensor_InvokeEvent1;
private static void HdxVibrationSensor_InvokeEvent1(object sender, EventArgs e)
{
Debug.WriteLine("Thr!!!");
if (!isVibrateAlarmOn)
{
return;
}
//Prevent From DDOS Sms Send.....
if ((DateTime.UtcNow - _smsSentDateTime).TotalSeconds < 60)
{
return;
}
Debug.WriteLine("send vibrate alarm");
var currebtDateTime = DateTime.UtcNow;
Thread.Sleep(100);
_smsSentDateTime = DateTime.UtcNow;
SendSms($"Detect Vibrate! {currebtDateTime.Hour}:{currebtDateTime.Minute}");
Thread.Sleep(100);
}
private static void SendSms(string message)
{
_m66R2?.SendSms(message, _phonenUmberToAlaram);
}
Actually we are in autumn and I have to wait for spring to deploy this solution on my garden :D
I am currently working on it. so I will update this post in the future.
Comments
Please log in or sign up to comment.