Ok, so after days of pulling my hair out I'm asking for help to figure out what I'm doing wrong with regards to adding a WeatherShield to my GarageMote.
if I separate the WeatherShielld code from the GarageMote sketch the temperature, humidity, and pressure values show up in the UI fine. See WeatherShield photo attached.
When I add the WeatherShield code to my GarageMote sketch the temperature, humidity, and pressure doesn't show. Although when opening terminal from the UI I see the GarageMote information being polled, the WeatherShield information isn't.
From terminal in UI;
8:31:28 AM : {"_id":3,"updated":1524832119993,"type":"GarageMote","label":"Garage Opener","descr":"[3]","metrics":{"Status":{"label":"Status","value":"UNKNOWN!","updated":1524829419021,"pin":1,"graph":1},"RSSI":{"label":"RSSI","value":-50,"unit":"db","updated":1524829419021,"graph":1}},"events":{"garagePoll":{"enabled":1,"executeDateTime":"2018-04-27T12:31:56.939Z"}}}
8:31:28 AM : GARAGE POLL STATUS: UNKNOWN!
Here is my sketch;
//#define WEATHERSHIELD_R1 //uncomment if WeatherShield_R1 (Si7021+BMP180 sensors) is present to report temp/humidity/pressure periodically
#define WEATHERSHIELD_R2 //uncomment if WeatherShield_R2 (BME280 sensor) is present to report temp/humidity/pressure periodically
#define WEATHERSENDDELAY 300000 // send WeatherShield data every so often (ms)
// ***************************************************************************************************************************
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
#ifdef WEATHERSHIELD_R1
#include <SFE_BMP180.h> //get it here: https://github.com/LowPowerLab/SFE_BMP180
#include <SI7021.h> //get it here: https://github.com/LowPowerLab/SI7021
#include <Wire.h>
#endif
#ifdef WEATHERSHIELD_R2
#include <SparkFunBME280.h> //get it here: https://github.com/sparkfun/SparkFun_BME280_Breakout_Board/tree/master/Libraries/Arduino/src
#include <Wire.h>
#endif
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define GATEWAYID 1
#define NODEID 3
#define NETWORKID 100
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define ENCRYPTKEY "sampleEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define IS_RFM69HW_HCW //uncomment only for RFM69HW/HCW! Leave out if you have RFM69W/CW!
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//*****************************************************************************************************************************
#define HALLSENSOR1 A0
#define HALLSENSOR1_EN 4
#define HALLSENSOR2 A1
#define HALLSENSOR2_EN 5
#define RELAYPIN1 6
#define RELAYPIN2 7
#define RELAY_PULSE_MS 250 //just enough that the opener will pick it up
#define DOOR_MOVEMENT_TIME 14000 // this has to be at least as long as the max between [door opening time, door closing time]
// my door opens and closes in about 12s
#define STATUS_CHANGE_MIN 1500 // this has to be at least as long as the delay
// between a opener button press and door movement start
// most garage doors will start moving immediately (within half a second)
//*****************************************************************************************************************************
#define HALLSENSOR_OPENSIDE 0
#define HALLSENSOR_CLOSEDSIDE 1
#define STATUS_CLOSED 0
#define STATUS_CLOSING 1
#define STATUS_OPENING 2
#define STATUS_OPEN 3
#define STATUS_UNKNOWN 4
#define LED 9 //pin connected to onboard LED
#define LED_PULSE_PERIOD 5000 //5s seems good value for pulsing/blinking (not too fast/slow)
#define SERIAL_BAUD 115200
#define SERIAL_EN //comment out if you don't want any serial output
#ifdef SERIAL_EN
#define DEBUG(input) {Serial.print(input); delay(1);}
#define DEBUGln(input) {Serial.println(input); delay(1);}
#else
#define DEBUG(input);
#define DEBUGln(input);
#endif
#ifdef WEATHERSHIELD_R1
SI7021 weatherShield_SI7021;
SFE_BMP180 weatherShield_BMP180;
#endif
#ifdef WEATHERSHIELD_R2
BME280 bme280;
#endif
//function prototypes
void setStatus(byte newSTATUS, boolean reportStatus=true);
void reportStatus();
boolean hallSensorRead(byte which);
void pulseRelay();
//global program variables
byte STATUS;
unsigned long lastStatusTimestamp=0;
unsigned long ledPulseTimestamp=0;
unsigned long lastWeatherSent=0;
int ledPulseValue=0;
boolean ledPulseDirection=false; //false=down, true=up
float temperature=0;
char Fstr[10];
float humidity=0;
char Hstr[10];
float pressure=0;
char sendBuf[32];
byte sendLen;
SPIFlash flash(8, 0xEF30); //WINDBOND 4MBIT flash chip on CS pin D8 (default for Moteino)
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
#endif
void setup(void)
{
#ifdef SERIAL_EN
Serial.begin(SERIAL_BAUD);
#endif
pinMode(HALLSENSOR1, INPUT);
pinMode(HALLSENSOR2, INPUT);
pinMode(HALLSENSOR1_EN, OUTPUT);
pinMode(HALLSENSOR2_EN, OUTPUT);
pinMode(RELAYPIN1, OUTPUT);
pinMode(RELAYPIN2, OUTPUT);
pinMode(LED, OUTPUT);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW_HCW
radio.setHighPower(); //must include this only for RFM69HW/HCW!
#endif
radio.encrypt(ENCRYPTKEY);
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
char buff[50];
sprintf(buff, "GarageMote : %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
DEBUGln(buff);
radio.sendWithRetry(GATEWAYID, "START", 5);
#ifdef ENABLE_ATC
DEBUGln("RFM69_ATC Enabled (Auto Transmission Control)\n");
#endif
if (flash.initialize()) flash.sleep(); //if Moteino has FLASH-MEM, make sure it sleeps
if (hallSensorRead(HALLSENSOR_OPENSIDE)==true)
setStatus(STATUS_OPEN);
if (hallSensorRead(HALLSENSOR_CLOSEDSIDE)==true)
setStatus(STATUS_CLOSED);
else setStatus(STATUS_UNKNOWN);
char Pstr[10];
char Fstr[10];
char Hstr[10];
#ifdef WEATHERSHIELD_R1
//initialize weather shield sensors
weatherShield_SI7021.begin();
if (weatherShield_BMP180.begin())
{ DEBUGln("BMP180 init success"); }
else { DEBUGln("BMP180 init fail\n"); }
#endif
#ifdef WEATHERSHIELD_R2
bme280.settings.commInterface = I2C_MODE;
bme280.settings.I2CAddress = 0x77;
bme280.settings.runMode = 3; //Normal mode
bme280.settings.tStandby = 0;
bme280.settings.filter = 0;
bme280.settings.tempOverSample = 1;
bme280.settings.pressOverSample = 1;
bme280.settings.humidOverSample = 1;
#endif
}
unsigned long doorPulseCount = 0;
char input=0;
double P;
void loop()
{
#ifdef SERIAL_EN
if (Serial.available())
input = Serial.read();
#endif
if (input=='r')
{
DEBUGln("Relay test...");
pulseRelay();
input = 0;
}
// UNKNOWN => OPEN/CLOSED
if (STATUS == STATUS_UNKNOWN && millis()-(lastStatusTimestamp)>STATUS_CHANGE_MIN)
{
if (hallSensorRead(HALLSENSOR_OPENSIDE)==true)
setStatus(STATUS_OPEN);
if (hallSensorRead(HALLSENSOR_CLOSEDSIDE)==true)
setStatus(STATUS_CLOSED);
}
// OPEN => CLOSING
if (STATUS == STATUS_OPEN && millis()-(lastStatusTimestamp)>STATUS_CHANGE_MIN)
{
if (hallSensorRead(HALLSENSOR_OPENSIDE)==false)
setStatus(STATUS_CLOSING);
}
// CLOSED => OPENING
if (STATUS == STATUS_CLOSED && millis()-(lastStatusTimestamp)>STATUS_CHANGE_MIN)
{
if (hallSensorRead(HALLSENSOR_CLOSEDSIDE)==false)
setStatus(STATUS_OPENING);
}
// OPENING/CLOSING => OPEN (when door returns to open due to obstacle or toggle action)
// => CLOSED (when door closes normally from OPEN)
// => UNKNOWN (when more time passes than normally would for a door up/down movement)
if ((STATUS == STATUS_OPENING || STATUS == STATUS_CLOSING) && millis()-(lastStatusTimestamp)>STATUS_CHANGE_MIN)
{
if (hallSensorRead(HALLSENSOR_OPENSIDE)==true)
setStatus(STATUS_OPEN);
else if (hallSensorRead(HALLSENSOR_CLOSEDSIDE)==true)
setStatus(STATUS_CLOSED);
else if (millis()-(lastStatusTimestamp)>DOOR_MOVEMENT_TIME)
setStatus(STATUS_UNKNOWN);
}
if (radio.receiveDone())
{
byte newStatus=STATUS;
boolean reportStatusRequest=false;
DEBUG('[');DEBUG(radio.SENDERID);DEBUG("] ");
for (byte i = 0; i < radio.DATALEN; i++)
DEBUG((char)radio.DATA[i]);
if (radio.DATALEN==3)
{
//check for an OPEN/CLOSE/STATUS request
if (radio.DATA[0]=='O' && radio.DATA[1]=='P' && radio.DATA[2]=='N')
{
if (millis()-(lastStatusTimestamp) > STATUS_CHANGE_MIN && (STATUS == STATUS_CLOSED || STATUS == STATUS_CLOSING || STATUS == STATUS_UNKNOWN))
newStatus = STATUS_OPENING;
//else radio.Send(requester, "INVALID", 7);
}
if (radio.DATA[0]=='C' && radio.DATA[1]=='L' && radio.DATA[2]=='S')
{
if (millis()-(lastStatusTimestamp) > STATUS_CHANGE_MIN && (STATUS == STATUS_OPEN || STATUS == STATUS_OPENING || STATUS == STATUS_UNKNOWN))
newStatus = STATUS_CLOSING;
//else radio.Send(requester, "INVALID", 7);
}
if (radio.DATA[0]=='S' && radio.DATA[1]=='T' && radio.DATA[2]=='S')
{
reportStatusRequest = true;
}
}
// wireless programming token check
// DO NOT REMOVE, or GarageMote will not be wirelessly programmable any more!
CheckForWirelessHEX(radio, flash, true);
//first send any ACK to request
DEBUG(" [RX_RSSI:");DEBUG(radio.RSSI);DEBUG("]");
if (radio.ACKRequested())
{
radio.sendACK();
DEBUG(" - ACK sent.");
}
//now take care of the request, if not invalid
if (STATUS != newStatus)
{
pulseRelay();
setStatus(newStatus);
}
if (reportStatusRequest)
{
reportStatus();
}
DEBUGln();
}
//use LED to visually indicate STATUS
if (STATUS == STATUS_OPEN || STATUS == STATUS_CLOSED) //solid ON/OFF
{
digitalWrite(LED, STATUS == STATUS_OPEN ? LOW : HIGH);
}
if (STATUS == STATUS_OPENING || STATUS == STATUS_CLOSING) //pulse
{
if (millis()-(ledPulseTimestamp) > LED_PULSE_PERIOD/256)
{
ledPulseValue = ledPulseDirection ? ledPulseValue + LED_PULSE_PERIOD/256 : ledPulseValue - LED_PULSE_PERIOD/256;
if (ledPulseDirection && ledPulseValue > 255)
{
ledPulseDirection=false;
ledPulseValue = 255;
}
else if (!ledPulseDirection && ledPulseValue < 0)
{
ledPulseDirection=true;
ledPulseValue = 0;
}
analogWrite(LED, ledPulseValue);
ledPulseTimestamp = millis();
}
}
if (STATUS == STATUS_UNKNOWN) //blink
{
if (millis()-(ledPulseTimestamp) > LED_PULSE_PERIOD/20)
{
ledPulseDirection = !ledPulseDirection;
digitalWrite(LED, ledPulseDirection ? HIGH : LOW);
ledPulseTimestamp = millis();
}
}
#if defined(WEATHERSHIELD_R1) || defined(WEATHERSHIELD_R2)
if (millis()-lastWeatherSent > WEATHERSENDDELAY)
{
lastWeatherSent = millis();
int fahrenheitHundreds=0;
int humidityPercent=0;
#ifdef WEATHERSHIELD_R1
//read Si7021 and BMP180 sensors
fahrenheitHundreds = weatherShield_SI7021.getFahrenheitHundredths();
humidityPercent = weatherShield_SI7021.getHumidityPercent();
P = getPressure();
P*=0.0295333727; //transform to inHg
dtostrf(P, 3,2, Pstr);
sprintf(sendBuf, "F:%d H:%d P:%s", fahrenheitHundreds, humidityPercent, Pstr);
#elsif defined(WEATHERSHIELD_R2)
//read BME280 sensor
bme280.begin();
dtostrf(bme280.readTempF(), 3,1, Fstr);
dtostrf(bme280.readFloatHumidity(), 2,0, Hstr);
float p = bme280.readFloatPressure();
p = p / 3311.8352; // this is conversion from Pascals to inches of mercury, adjusted for my location above sea level
dtostrf(p, 2,2, Pstr);
bme280.writeRegister(BME280_CTRL_MEAS_REG, 0x00); //sleep the BME280
sprintf(sendBuf, "F:%s H:%s P:%s", Fstr, Hstr, Pstr); // we skip transmitting battery voltage to save battery life
#endif
byte sendLen = strlen(sendBuf);
radio.send(GATEWAYID, sendBuf, sendLen);
}
#endif
}
//returns TRUE if magnet is next to sensor, FALSE if magnet is away
boolean hallSensorRead(byte which)
{
//while(millis()-lastStatusTimestamp<STATUS_CHANGE_MIN);
digitalWrite(which ? HALLSENSOR2_EN : HALLSENSOR1_EN, HIGH); //turn sensor ON
delay(1); //wait a little
byte reading = digitalRead(which ? HALLSENSOR2 : HALLSENSOR1);
digitalWrite(which ? HALLSENSOR2_EN : HALLSENSOR1_EN, LOW); //turn sensor OFF
return reading==0;
}
void setStatus(byte newSTATUS, boolean reportIt)
{
if (STATUS != newSTATUS) lastStatusTimestamp = millis();
STATUS = newSTATUS;
DEBUGln(STATUS==STATUS_CLOSED ? "CLOSED" : STATUS==STATUS_CLOSING ? "CLOSING" : STATUS==STATUS_OPENING ? "OPENING" : STATUS==STATUS_OPEN ? "OPEN" : "UNKNOWN");
if (reportIt)
reportStatus();
}
void reportStatus(void)
{
char buff[10];
sprintf(buff, STATUS==STATUS_CLOSED ? "CLOSED" : STATUS==STATUS_CLOSING ? "CLOSING" : STATUS==STATUS_OPENING ? "OPENING" : STATUS==STATUS_OPEN ? "OPEN" : "UNKNOWN");
byte len = strlen(buff);
radio.sendWithRetry(GATEWAYID, buff, len);
}
void pulseRelay()
{
digitalWrite(RELAYPIN1, HIGH);
digitalWrite(RELAYPIN2, HIGH);
delay(RELAY_PULSE_MS);
digitalWrite(RELAYPIN1, LOW);
digitalWrite(RELAYPIN2, LOW);
}
void Blink(byte PIN, byte DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
#ifdef WEATHERSHIELD_R1
double getPressure()
{
char status;
double T,P,p0,a;
// If you want sea-level-compensated pressure, as used in weather reports,
// you will need to know the altitude at which your measurements are taken.
// We're using a constant called ALTITUDE in this sketch:
// If you want to measure altitude, and not pressure, you will instead need
// to provide a known baseline pressure. This is shown at the end of the sketch.
// You must first get a temperature measurement to perform a pressure reading.
// Start a temperature measurement:
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = weatherShield_BMP180.startTemperature();
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed temperature measurement:
// Note that the measurement is stored in the variable T.
// Function returns 1 if successful, 0 if failure.
status = weatherShield_BMP180.getTemperature(T);
if (status != 0)
{
// Start a pressure measurement:
// The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = weatherShield_BMP180.startPressure(3);
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed pressure measurement:
// Note that the measurement is stored in the variable P.
// Note also that the function requires the previous temperature measurement (T).
// (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
// Function returns 1 if successful, 0 if failure.
status = weatherShield_BMP180.getPressure(P,T);
if (status != 0)
{
return P;
}
}
}
}
return 0;
}
#endif
Here is my GarageMote / WeatherShield metrics;
exports.metrics = {
//GarageMote
//NOTE the \b word boundary is used to avoid matching "OPENING" (ie OPEN must be followed by word boundary/end of word)
open : { name:'Status', regexp:/(?:STS\:)?(OPN|OPEN)\b/i, value:'OPEN', pin:1, graph:1, logValue:2, graphOptions:{ legendLbl:'Garage door events', yaxis: {ticks:0}, colors:['#4a0'], /*lines: { lineWidth:1 }*/}},
opening : { name:'Status', regexp:/(?:STS\:)?(OPNING|OPENING)/i, value:'OPENING..', pin:1, graph:1, logValue:1 },
closed : { name:'Status', regexp:/(?:STS\:)?(CLS|CLOSED)/i, value:'CLOSED', pin:1, graphValPrefix:' Door: ', graph:1, logValue:0 },
closing : { name:'Status', regexp:/(?:STS\:)?(CLSING|CLOSING)/i, value:'CLOSING..', pin:1, graph:1, logValue:1.1 }, //1.1 to avoid a match with "OPENING"
unknown : { name:'Status', regexp:/(?:STS\:)?(UNK|UNKNOWN)/i, value:'UNKNOWN!', pin:1, graph:1, logValue:0.5 },
//WeatherShield metrics
//uncomment FtoC if you want a F:1234 to be valuated as a Centigrade isntead of F (the first match is picked up and will evaluate, any following defs are ignored)
//FtoC : { name:'C', regexp:/F\:(-?\d+\.\d+)/i, value:'', duplicateInterval:3600, valuation:function(value) {return (value - 32) * 5/9;}, unit:'°', pin:1, graph:1, graphValSuffix:'C', graphOptions:{ legendLbl:'Temperature', lines: { lineWidth:1 }}}
F : { name:'F', regexp:/\bF\:(-?\d+\.\d+)\b/i, value:'', duplicateInterval:3600, unit:'°', pin:1, graph:1, graphValSuffix:'F', graphOptions:{ legendLbl:'Temperature', lines: { lineWidth:1 } }},
//uncomment FHtoC if you want a F:1234 to be valuated as a Centigrade isntead of F (the first match is picked up and will evaluate, any following defs are ignored)
//FHtoC : { name:'C', regexp:/\bF\:(-?\d+)\b/i, value:'', duplicateInterval:3600, valuation:function(value) {return (value/100 - 32) * 5/9;}, unit:'°', pin:1, graph:1, graphValSuffix:'C', graphOptions:{ legendLbl:'Temperature', lines: { lineWidth:1 }}}
FH : { name:'F', regexp:/\bF\:(-?\d+)\b/i, value:'', duplicateInterval:3600, valuation:function(value) {return value/100;}, unit:'°', pin:1, graph:1, graphValSuffix:'F', graphOptions:{ legendLbl:'Temperature', lines: { lineWidth:1 }}},
C : { name:'C', regexp:/\bC\:([-\d\.]+)\b/i, value:'', duplicateInterval:3600, unit:'°', pin:1, graph:1, graphValSuffix:'C', graphOptions:{ legendLbl:'Temperature' }},
H : { name:'H', regexp:/\bH\:([\d\.]+)\b/i, value:'', duplicateInterval:3600, unit:'%', pin:1, graph:1, graphOptions:{ legendLbl:'Humidity', lines: { lineWidth:1 }}},
P : { name:'P', regexp:/\bP\:([\d\.]+)\b/i, value:'', duplicateInterval:3600, unit:'"', pin:1, },
};
exports.events = {
garageSMSO : { label:'Garage opening : SMS', icon:'comment', descr:'Send SMS when garage is OPENING', serverExecute:function(node) { if (node.metrics['Status'] && (node.metrics['Status'].value.indexOf('OPENING')>-1) && (Date.now() - new Date(node.metrics['Status'].updated).getTime() < 2000)) { sendSMS('Garage event', 'Garage was opening on node : [' + node._id + ':' + node.label + '] @ ' + new Date().toLocaleTimeString()); }; } },
garageSMSC : { label:'Garage closing : SMS', icon:'comment', descr:'Send SMS when garage is CLOSING', serverExecute:function(node) { if (node.metrics['Status'] && (node.metrics['Status'].value.indexOf('CLOSING')>-1) && (Date.now() - new Date(node.metrics['Status'].updated).getTime() < 2000)) { sendSMS('Garage event', 'Garage was closing on node : [' + node._id + ':' + node.label + '] @ ' + new Date().toLocaleTimeString()); }; } },
garageEmailO : { label:'Garage opening : Email', icon:'mail', descr:'Send Email when garage is OPENING', serverExecute:function(node) { if (node.metrics['Status'] && (node.metrics['Status'].value.indexOf('OPENING')>-1) && (Date.now() - new Date(node.metrics['Status'].updated).getTime() < 2000)) { sendEmail('Garage event', 'Garage was opening on node : [' + node._id + ':' + node.label + '] @ ' + new Date().toLocaleTimeString()); }; } },
garageEmailC : { label:'Garage closing : Email', icon:'mail', descr:'Send Email when garage is CLOSING', serverExecute:function(node) { if (node.metrics['Status'] && (node.metrics['Status'].value.indexOf('CLOSING')>-1) && (Date.now() - new Date(node.metrics['Status'].updated).getTime() < 2000)) { sendEmail('Garage event', 'Garage was closing on node : [' + node._id + ':' + node.label + '] @ ' + new Date().toLocaleTimeString()); }; } },
};
exports.motes = {
GarageMote : {
label : 'Garage Opener',
icon : 'icon_garage.png',
controls : { refresh : { states: [{ label:'Refresh', action:'STS', icon:'refresh' }]},
opencls : { states: [{ label:'Open!', action:'OPN', icon:'arrow-u', css:'background-color:#FF9B9B;', condition:''+function(node) { return node.metrics['Status'].value == 'CLOSED';}},
{ label:'Opening..', action:'', icon:'forbidden', css:'background-color:#FFF000;', condition:''+function(node) { return node.metrics['Status'].value == 'OPENING';}},
{ label:'Close!', action:'CLS', icon:'arrow-d', css:'background-color:#9BFFBE;color:#000000', condition:''+function(node) { return node.metrics['Status'].value == 'OPEN';}},
{ label:'Closing..', action:'', icon:'forbidden', css:'background-color:#FFF000;', condition:''+function(node) { return node.metrics['Status'].value == 'CLOSING';}}]
}
}
},
}
Appreciate any input..
Thanks!
what do you mean, when I add the code... (I know what you mean... rhetorical )
Look at buff, this is what you send. In your buff, you only put in
sprintf(buff, STATUS==STATUS_CLOSED ? "CLOSED" : STATUS==STATUS_CLOSING ? "CLOSING" : STATUS==STATUS_OPENING ? "OPENING" : STATUS==STATUS_OPEN ? "OPEN" : "UNKNOWN");
At no point you put in any data from weather shield. That is just garage stuff
Why don't you just combine two sketches, send part for garage, and then with second radio.sendWithRetry, send P, H and whatever else with the SAME ID
you need to have something like
sprintf(buff, "BAT:%sv F:%s H:%s P:%s", BATstr, Fstr, Hstr, Pstr); also in the code.
OR combine from both into one, as long as your sending length is below max of 65 or what it was... but you can also try to go over that, to see how part of the data will be cut off :)
Thanks for the response Luka
Instead of saying "when I add the code.." I should have said when I combine the garagemote and weathershield code.. sorry for the confusion..
Shouldn't this code send the data of the weather shield; (it's located about 3/4 of the way thru the sketch..)
#elsif defined(WEATHERSHIELD_R2)
//read BME280 sensor
bme280.begin();
dtostrf(bme280.readTempF(), 3,1, Fstr);
dtostrf(bme280.readFloatHumidity(), 2,0, Hstr);
float p = bme280.readFloatPressure();
p = p / 3311.8352; // this is conversion from Pascals to inches of mercury, adjusted for my location above sea level
dtostrf(p, 2,2, Pstr);
bme280.writeRegister(BME280_CTRL_MEAS_REG, 0x00); //sleep the BME280
sprintf(sendBuf, "F:%s H:%s P:%s", Fstr, Hstr, Pstr); // we skip transmitting battery voltage to save battery life
#endif
I will try your suggestions
Have you defined WEATHERSHIELD_R2?
Quote from: LukaQ on April 27, 2018, 09:34:19 AM
Why don't you just combine two sketches, send part for garage, and then with second radio.sendWithRetry, send P, H and whatever else with the SAME ID
Ok, at first I thought I knew how to go about doing this but apparently not, I'm confused..
Quote from: ssmall on April 27, 2018, 10:38:39 AM
Have you defined WEATHERSHIELD_R2?
I was looking at this;
#ifdef WEATHERSHIELD_R2
#include <SparkFunBME280.h> //get it here: https://github.com/sparkfun/SparkFun_BME280_Breakout_Board/tree/master/Libraries/Arduino/src
#include <Wire.h>
#endif
thinking it was.. I guess I didn't :P
Thank you!
Quote from: ssmall on April 27, 2018, 10:38:39 AM
Have you defined WEATHERSHIELD_R2?
Yes, it was there..
//#define WEATHERSHIELD_R1 //uncomment if WeatherShield_R1 (Si7021+BMP180 sensors) is present to report temp/humidity/pressure periodically
#define WEATHERSHIELD_R2 //uncomment if WeatherShield_R2 (BME280 sensor) is present to report temp/humidity/pressure periodically
#define WEATHERSENDDELAY 300000 // send WeatherShield data every so often (ms)
Did you check, that you do enter either one, R1 or R2 with something like serial.print?
Also note, that Sparkfun and I changed the code to newer code, what you have still works. Sleep mode is more easy to use (read as: you have it without changing anything)
Try putting this: DEBUGln(sendBuf)
After the following code and see what is printed for sendBuf:
#elsif defined(WEATHERSHIELD_R2)
//read BME280 sensor
bme280.begin();
dtostrf(bme280.readTempF(), 3,1, Fstr);
dtostrf(bme280.readFloatHumidity(), 2,0, Hstr);
float p = bme280.readFloatPressure();
p = p / 3311.8352; // this is conversion from Pascals to inches of mercury, adjusted for my location above sea level
dtostrf(p, 2,2, Pstr);
bme280.writeRegister(BME280_CTRL_MEAS_REG, 0x00); //sleep the BME280
sprintf(sendBuf, "F:%s H:%s P:%s", Fstr, Hstr, Pstr); // we skip transmitting battery voltage to save battery life
#endif
Here is all I get;
I think you need to change your code to
#ifdef WEATHERSHIELD_R1
//
#endif
#ifdef WEATHERSHIELD_R2
//
#endif
You were not entering
#elsif defined(WEATHERSHIELD_R2)
//read BME280 sensor
bme280.begin();
dtostrf(bme280.readTempF(), 3,1, Fstr);
dtostrf(bme280.readFloatHumidity(), 2,0, Hstr);
float p = bme280.readFloatPressure();
p = p / 3311.8352; // this is conversion from Pascals to inches of mercury, adjusted for my location above sea level
dtostrf(p, 2,2, Pstr);
bme280.writeRegister(BME280_CTRL_MEAS_REG, 0x00); //sleep the BME280
sprintf(sendBuf, "F:%s H:%s P:%s", Fstr, Hstr, Pstr); // we skip transmitting battery voltage to save battery life
#endif
QuoteI think you need to change your code to
#ifdef WEATHERSHIELD_R1
//
#endif
#ifdef WEATHERSHIELD_R2
//
#endif
Didn't work.. no data
QuoteWhy don't you just combine two sketches, send part for garage, and then with second radio.sendWithRetry, send P, H and whatever else with the SAME ID
Any tips how I can go about doing this?
man I would love to test, but I'm packing for few day of holiday and I only have moteino without RFM in front of me
Try my sketch, you will see you do enter 1, then 2 and R2 as last. If this happens with other code enabled, then you are probably sending it also. You could set one moteino RF to serial, the other sketch that is not PIgateway, just gateway
GarageMote : 868 Mhz...
RFM69_ATC Enabled (Auto Transmission Control)
OPEN
CLOSED
1
1
1
1
1
1
2
R2
1
1
First make sure the readings from the WeatherShield are valid, use the WeatherShield example for that just to send weather readings.
Then you can combine those into the GarageMote similar to how the older example does it with BMP180.
Quote from: Felix on April 27, 2018, 11:56:14 AM
First make sure the readings from the WeatherShield are valid, use the WeatherShield example for that just to send weather readings.
Then you can combine those into the GarageMote similar to how the older example does it with BMP180.
Yes, as stated, the weather shield is working great when the code is separated from the GarageMote.. it's when I do the combining (GarageMote_WS) the data for the weather shield stops transmitting.
Thanks
Quote from: LukaQ on April 27, 2018, 11:58:20 AM
Sometime next week I can help you with that, to have more up to date sketches
Thanks Luka, at first try your sketch did not work but I'll keep trying.. Enjoy your vacation and thanks for all the input. Talk to you next week, hopefully with some good news!!
wait what? how does it not work? that should work on any arduino, with no RFM or FLASH or sensors/halls. Let me test your code really fast, I won't be able to sleep, thinking about it ;D
Here you go, working
Quote from: LukaQ on April 27, 2018, 01:01:03 PM
Here you go, working
You are the man!!!! I will do a compare to see what mistake(s) I made.. Thank you so much Luka.. Have a GREAT vacation..
I thank everyone for their input and suggestions with this issue..
So it looks like using #ifdef / #endif instead of #elsif / #endif did the trick. Any idea why that is?
How close can one be but yet so far away.. :P
Thanks again!