i have found the post. But i don't now how i implement it... i'm just a beginner and make copy and paste
if (attachedServo && millis() - timeOfLastChange > DETACH_DELAY) {
myservo.detach();
attachedServo = false;
}``````
can you help me?
i have found the post. But i don't now how i implement it... i'm just a beginner and make copy and paste
if (attachedServo && millis() - timeOfLastChange > DETACH_DELAY) {
myservo.detach();
attachedServo = false;
}``````
can you help me?
hi,
i woud to use this sketch to show messages fron my pimatic controller on a 1602 Display.
This sketch use the V_TEXT variabel to show messages.
How i can use V_TEXT in pimatic to push messages to the display?
//Credits: https://forum.mysensors.org/topic/1957/lcd-clock-and-text-sensor-node-with-new-v_text
//Soft signing.
//#define MY_SIGNING_SOFT
//#define MY_SIGNING_REQUEST_SIGNATURES
//#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
#define MY_RADIO_NRF24
#define MY_DEBUG
#define MY_NODE_ID 3
#include <TimeLib.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <MySensors.h>
char lastLCD1[16] = "Line1"; //Line 1 always showing current time
char lastLCD2[16] = "Line2";
//20 whitespace characters used to clear your LCD line before printing to it.
//Change to fit your LCD. Don't forget to change number of chars in the writeScreen function if needed.
String LINE_BLANK = " ";
boolean timeReceived = false ;
unsigned long lastUpdate = 0, lastRequest = 0, lastDisplay = 0;
const byte LCD1_CHILD = 1; // Child ID for LCD line 1
const byte LCD2_CHILD = 2; // Child ID for LCD line 2
MyMessage textMsg(0, V_TEXT);
// Initialize display. Google the correct settings for your display.
// The follwoing setting should work for the recommended display in the MySensors "shop".
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
void before() {
Wire.begin(); // I2C.
lcd.begin(16, 2); // LCD with 20 chars, 4 lines.
lcd.setBacklight(HIGH); // Make sure backlight is on.
writeScreen(0, "Waiting for GW.."); // Print initial text before contact with GW.
}
void setup(void)
{
Serial.begin(115200); // Start serial.
requestTime(); // Request time from controller.
}
void presentation() {
sendSketchInfo("Domoticz LCD", "1.0"); // Send the sketch version information to the gateway and Controller
present(LCD1_CHILD, S_INFO, "LCD_line1");
wait(500);
present(LCD2_CHILD, S_INFO, "LCD_line2");
wait(500);
send(textMsg.setSensor(LCD1_CHILD).set("-")); // initialize the V_TEXT at controller for sensor to none (trick for Domoticz)
send(textMsg.setSensor(LCD2_CHILD).set("-"));
}
void loop() {
// timer for loop delays
unsigned long now = millis();
// If no time has been received yet, request it every 10 second from controller
// When time has been received, request update every hour
if ((!timeReceived && (now - lastRequest > 10 * 1000)) ||
(now - lastRequest > 3600000UL)) { // request update from GW every hour to keep in sync
// Request time from controller.
Serial.println("Requesting time...");
timeReceived = false;
requestTime();
lastRequest = now;
}
// Update sensors every 5 seconds
if (now - lastDisplay > 5000) {
lastDisplay = now;
request(LCD1_CHILD, V_TEXT, 0); // request new values from controller
request(LCD2_CHILD, V_TEXT, 0); // request new values from controller
}
// Update LCD time every second
if (now - lastUpdate > 1000) {
LCD_time();
lastUpdate = now;
}
}
// This is called when a message is received
void receive(const MyMessage &message) {
if (message.type == V_TEXT) { // Text messages only
Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString()); // Write some debug info
if (message.sensor == LCD1_CHILD) {
writeScreen(0, message.data);
}
// Don't forget to change "if" to "else if" when controlling all 4 lines:
else if (message.sensor == LCD2_CHILD) {
writeScreen(1, message.data);
}
}
}
void receiveTime(unsigned long ts) {
setTime(ts);
timeReceived = true;
}
void LCD_time(void) {
lcd.setCursor(0, 0);
if (timeReceived) {
lcd.print(day());
lcd.print(".");
printDigits(month());
lcd.print(".");
printDigits(year());
lcd.print(" ");
printDigits(hour());
lcd.print(":");
printDigits(minute());
} else {
writeScreen(0, "Waiting for time...");
}
}
void printDigits(int digits) {
//add leading 0 if digit = 0-9
if (digits < 10)
lcd.print('0');
lcd.print(digits);
}
void writeScreen(int line, String text)
{
// Remove anything over 20 char in text.
if (text.length() > 19)
{
text.remove(20);
}
// Clear the line
lcd.setCursor(0, line);
lcd.print(LINE_BLANK);
// Set Line
lcd.setCursor(0, line);
lcd.print(text);
}```
Hello,
ich habe Probleme beim empfangen von Events bei meinem Sensor.
Mein Sensor läuft ganz gut (MQ und DHT) nur das schalten eines Relais funktioniert nicht da, void receive nicht richtig ausgeführt wird. Wenn ich aber sleep entferne, bekomme ich keine Daten mehr von dem dht da der UPDATE_INTERVAL nicht zu hoch sein darf. Wenn ich den sleep entferne reagiert das relai. Wenn nicht dann nicht. Was kann ich machen damit ich auch Daten empfangen kann?
i have a problem by revice events from my sensor.
my sensor work well (MQ and DHT) but the trigger of a relai does not working. I think that the void receive will not be performed. If i remove the sleep command i receive no data from my dht sensor because the UPDATE_INTERVAL ist to hight for the dht but the trigger of my relai ist working. if i set the sleep command the receive is not working. What can i do the the receiveing ist working?
/*
Arduino MQ135
connect the sensor as follows :
A H A >>> 5V
B >>> A0
H >>> GND
B >>> 10K ohm >>> GND
Contribution: epierre
Based on David Gironi http://davidegironi.blogspot.fr/2014/01/cheap-co2-meter-using-mq135-sensor-with.html
http://skylink.dl.sourceforge.net/project/davidegironi/avr-lib/avr_lib_mq135_01.zip
*/
// Enable debug prints
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_NRF24
#define MY_NODE_ID 4
#include <MySensors.h>
#include <Wire.h>
#include <SPI.h>
#include <DHT.h>
// RELAY
#define RELAY_1 4 // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
#define NUMBER_OF_RELAYS 1 // Total number of attached relays
#define RELAY_ON 1 // GPIO value to write to turn on attached relay
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
// DHT
#define DHT_DATA_PIN 3
#define SENSOR_TEMP_OFFSET 0
static const uint64_t UPDATE_INTERVAL = 60000;
static const uint8_t FORCE_UPDATE_N_READS = 10;
#define CHILD_ID_HUM 2
#define CHILD_ID_TEMP 3
float lastTemp;
float lastHum;
uint8_t nNoUpdatesTemp;
uint8_t nNoUpdatesHum;
bool metric = true;
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
DHT dht;
// MQ
#define CHILD_ID_AIQ 4
#define AIQ_SENSOR_ANALOG_PIN 0
#define MQ135_DEFAULTPPM 399 //default ppm of CO2 for calibration
#define MQ135_DEFAULTRO 68550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
#define MQ135_SCALINGFACTOR 116.6020682 //CO2 gas value
#define MQ135_EXPONENT -2.769034857 //CO2 gas value
#define MQ135_MAXRSRO 2.428 //for CO2
#define MQ135_MINRSRO 0.358 //for CO2
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in seconds)
//VARIABLES
float mq135_ro = 10000.0; // this has to be tuned 10K Ohm
int val = 0; // variable to store the value coming from the sensor
float valAIQ =0.0;
float lastAIQ =0.0;
MyMessage msg(CHILD_ID_AIQ, V_LEVEL);
void before()
{
for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
// Then set relay pins in output mode
pinMode(pin, OUTPUT);
// Set relay to last known state (using eeprom storage)
digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
}
}
void setup()
{
dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
}
// Sleep for the time of the minimum sampling period to give the sensor time to power up
// (otherwise, timeout errors might occure for the first reading)
sleep(dht.getMinimumSamplingPeriod());
}
void presentation()
{
// Send the sketch version information to the gateway and Controller
sendSketchInfo("MQ DHT LED Switch", "1.0");
// Register all sensors to gw (they will be created as child devices)
present(CHILD_ID_AIQ, S_AIR_QUALITY);
// Register all sensors to gw (they will be created as child devices)
present(CHILD_ID_HUM, S_HUM);
present(CHILD_ID_TEMP, S_TEMP);
metric = getControllerConfig().isMetric;
// RELAI
for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
// Register all sensors to gw (they will be created as child devices)
present(sensor, S_BINARY);
}
}
/*
* get the calibrated ro based upon read resistance, and a know ppm
*/
long mq135_getro(long resvalue, double ppm) {
return (long)(resvalue * exp( log(MQ135_SCALINGFACTOR/ppm) / MQ135_EXPONENT ));
}
/*
* get the ppm concentration
*/
double mq135_getppm(long resvalue, long ro) {
double ret = 0;
double validinterval = 0;
validinterval = resvalue/(double)ro;
if(validinterval<MQ135_MAXRSRO && validinterval>MQ135_MINRSRO) {
ret = (double)MQ135_SCALINGFACTOR * pow( ((double)resvalue/ro), MQ135_EXPONENT);
}
return ret;
}
void loop()
{
// MQ
uint16_t valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
Serial.println(val);
uint16_t val = ((float)22000*(1023-valr)/valr);
//during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
//convert to ppm (using default ro)
valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
Serial.print ( "Val / Ro / value:");
Serial.print ( val);
Serial.print ( " / ");
Serial.print ( mq135_ro);
Serial.print ( " / ");
Serial.print ( valAIQ);
if (valAIQ != lastAIQ) {
// gw.send(msg.set(MQ135_DEFAULTPPM+(int)ceil(valAIQ)));
send(msg.set(MQ135_DEFAULTPPM+(int)ceil(valAIQ)));
lastAIQ = ceil(valAIQ);
}
// Power down the radio. Note that the radio will get powered back up
// on the next write() call.
//gw.sleep(SLEEP_TIME); //sleep for: sleepTime
sleep(SLEEP_TIME); //sleep for: sleepTime
//DHT
// Force reading sensor, so it works also after sleep()
dht.readSensor(true);
// Get temperature from DHT library
float temperature = dht.getTemperature();
if (isnan(temperature)) {
Serial.println("Failed reading temperature from DHT!");
} else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
// Only send temperature if it changed since the last measurement or if we didn't send an update for n times
lastTemp = temperature;
if (!metric) {
temperature = dht.toFahrenheit(temperature);
}
// Reset no updates counter
nNoUpdatesTemp = 0;
temperature += SENSOR_TEMP_OFFSET;
send(msgTemp.set(temperature, 1));
#ifdef MY_DEBUG
Serial.print("T: ");
Serial.println(temperature);
#endif
} else {
// Increase no update counter if the temperature stayed the same
nNoUpdatesTemp++;
}
// Get humidity from DHT library
float humidity = dht.getHumidity();
if (isnan(humidity)) {
Serial.println("Failed reading humidity from DHT");
} else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
// Only send humidity if it changed since the last measurement or if we didn't send an update for n times
lastHum = humidity;
// Reset no updates counter
nNoUpdatesHum = 0;
send(msgHum.set(humidity, 1));
#ifdef MY_DEBUG
Serial.print("H: ");
Serial.println(humidity);
#endif
} else {
// Increase no update counter if the humidity stayed the same
nNoUpdatesHum++;
}
// Sleep for a while to save energy
sleep(UPDATE_INTERVAL);
}
/***************************** MQGetPercentage **********************************
Input: rs_ro_ratio - Rs divided by Ro
pcurve - pointer to the curve of the target gas
Output: ppm of the target gas
Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
of the line could be derived if y(rs_ro_ratio) is provided. As it is a
logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
value.
************************************************************************************/
int MQGetPercentage(float rs_ro_ratio, float ro, float *pcurve)
{
return (double)(pcurve[0] * pow(((double)rs_ro_ratio/ro), pcurve[1]));
}
void receive(const MyMessage &message)
{
// We only expect one type of message from controller. But we better check anyway.
if (message.type==V_STATUS) {
// Change relay state
digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
// Store state in eeprom
saveState(message.sensor, message.getBool());
// Write some debug info
Serial.print("Incoming change for sensor:");
Serial.print(message.sensor);
Serial.print(", New status: ");
Serial.println(message.getBool());
}
}
thank you. it works:)
hello,
i would like to build a MQ135 AirQuality Sensor. The sketch i have found from empierre ist not compatible with the 2.0 libery. I don`t know what i musst change on this sketch. Can anyone help me?
/*
Arduino MQ135
connect the sensor as follows :
A H A >>> 5V
B >>> A0
H >>> GND
B >>> 10K ohm >>> GND
Contribution: epierre
Based on David Gironi http://davidegironi.blogspot.fr/2014/01/cheap-co2-meter-using-mq135-sensor-with.html
http://skylink.dl.sourceforge.net/project/davidegironi/avr-lib/avr_lib_mq135_01.zip
*/
#include <SPI.h>
#include <MySensor.h>
#include <Wire.h>
#define CHILD_ID_AIQ 0
#define AIQ_SENSOR_ANALOG_PIN 0
#define MQ135_DEFAULTPPM 399 //default ppm of CO2 for calibration
#define MQ135_DEFAULTRO 68550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
#define MQ135_SCALINGFACTOR 116.6020682 //CO2 gas value
#define MQ135_EXPONENT -2.769034857 //CO2 gas value
#define MQ135_MAXRSRO 2.428 //for CO2
#define MQ135_MINRSRO 0.358 //for CO2
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in seconds)
//VARIABLES
float mq135_ro = 10000.0; // this has to be tuned 10K Ohm
int val = 0; // variable to store the value coming from the sensor
float valAIQ =0.0;
float lastAIQ =0.0;
MySensor gw;
MyMessage msg(CHILD_ID_AIQ, V_LEVEL);
void setup()
{
gw.begin();
// Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("AIQ Sensor MQ135", "1.0");
// Register all sensors to gateway (they will be created as child devices)
gw.present(CHILD_ID_AIQ, S_AIR_QUALITY);
}
/*
* get the calibrated ro based upon read resistance, and a know ppm
*/
long mq135_getro(long resvalue, double ppm) {
return (long)(resvalue * exp( log(MQ135_SCALINGFACTOR/ppm) / MQ135_EXPONENT ));
}
/*
* get the ppm concentration
*/
double mq135_getppm(long resvalue, long ro) {
double ret = 0;
double validinterval = 0;
validinterval = resvalue/(double)ro;
if(validinterval<MQ135_MAXRSRO && validinterval>MQ135_MINRSRO) {
ret = (double)MQ135_SCALINGFACTOR * pow( ((double)resvalue/ro), MQ135_EXPONENT);
}
return ret;
}
void loop()
{
uint16_t valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
Serial.println(val);
uint16_t val = ((float)22000*(1023-valr)/valr);
//during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
//convert to ppm (using default ro)
valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
Serial.print ( "Val / Ro / value:");
Serial.print ( val);
Serial.print ( " / ");
Serial.print ( mq135_ro);
Serial.print ( " / ");
Serial.print ( valAIQ);
if (valAIQ != lastAIQ) {
gw.send(msg.set(MQ135_DEFAULTPPM+(int)ceil(valAIQ)));
lastAIQ = ceil(valAIQ);
}
// Power down the radio. Note that the radio will get powered back up
// on the next write() call.
gw.sleep(SLEEP_TIME); //sleep for: sleepTime
}
/***************************** MQGetPercentage **********************************
Input: rs_ro_ratio - Rs divided by Ro
pcurve - pointer to the curve of the target gas
Output: ppm of the target gas
Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
of the line could be derived if y(rs_ro_ratio) is provided. As it is a
logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
value.
************************************************************************************/
int MQGetPercentage(float rs_ro_ratio, float ro, float *pcurve)
{
return (double)(pcurve[0] * pow(((double)rs_ro_ratio/ro), pcurve[1]));
}