hello, I am in the process of building a monitoring system for my bee hives. I currently have a RedBoard qwiic, and the following sensors working together:
SEN-14348 (CCS811/BME280 Combo)
SEN-15892 (Loudness Sensor)
SEN-15242 (NAU7802 Load Sensor)
BOB-14558 (RTC)
I recently added a WRL-13287 (WiFi Shield) and it is breaking my system. The setup locks up after detecting the SEN-14348. If I remove the sensors and add the WRL-13287, I can get it connected to my network. My next troubleshooting step is to add each sensor separately to see if one in particular is conflicting with the WiFi adapter. Any help or advice would be appreciated.
The code that I’m using for the sensors is included.
/******************************************************************************
Sketch to read from the following sensors for the purpose of monitoring
bee hives.
SEN-14348 (CCS811/BME280 Combo)
SEN-15892 (Loudness Sensor)
WRL-13287 (WiFi Shield)
SEN-15242 (NAU7802 Load Sensor)
Pulled from multiple examples found on the internet
Author: David Boyd
File Name: BeeHive_Master
Date Created: 24MAY2019
Date Modified: 27JAN2020
******************************************************************************/
#include <Wire.h>
#include <SparkFunBME280.h>
#include <SparkFunCCS811.h>
#include <EEPROM.h> //Needed to record user settings
#include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h" // Click here to get the library: [http://librarymanager/All#SparkFun_NAU8702](http://librarymanager/All#SparkFun_NAU8702)
#define COMMAND_LED_OFF 0x00
#define COMMAND_LED_ON 0x01
#define COMMAND_GET_VALUE 0x05
#define COMMAND_NOTHING_NEW 0x99
#define CCS811_ADDR 0x5B //Default I2C Address
//#define CCS811_ADDR 0x5A //Alternate I2C Address
#define AVG_SIZE 4
#define LOCATION_CALIBRATION_FACTOR 0 //Float, requires 4 bytes of EEPROM
#define LOCATION_ZERO_OFFSET 10 //Must be more than 4 away from previous spot. Long, requires 4 bytes of EEPROM
//Global environmental sensor objects
CCS811 myCCS811(CCS811_ADDR);
BME280 myBME280;
NAU7802 myScale; //Create instance of the NAU7802 class
//EEPROM locations to store 4-byte variables for NAU7802 Scale
bool settingsDetected = false; //Used to prompt user to calibrate their scale
// SETTINGS FOR AVERAGING
const int numReadings = 10; // number of readings for the average
const int sketch_delay = 2000; // delay between readings
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
unsigned int ADC_total = 0; // running total for ADC
unsigned int CO2_total = 0; // running total for CO2
unsigned int TVOC_total = 0; // running total for TVOC
unsigned int TEMP_total = 0; // running total for TEMP
unsigned int H2O_total = 0; // running total for H2O
unsigned int PRES_total = 0; // running total for Pressure
unsigned int ALT_total = 0; // running total for Altitude
unsigned int WGT_total = 0; // running total for Scale
int ADC_average = 0; // ADC the average (noise)
int CO2_average = 0; // CO2 average
int TVOC_average = 0; // TVOC average
int TEMP_average = 0; // Temperature average
int H2O_average = 0; // Humidity average
int PRES_average = 0; // Barometric pressure average
int ALT_average = 0; // Altitude average in ft.
int WGT_average = 0; // Scale average
const byte qwiicAddress = 0x38; //Default Address
uint16_t ADC_VALUE = 0;
void setup() {
Serial.begin(9600);
Serial.println();
Serial.println("Apply BME280 data to CCS811 for compensation.");
Serial.println("Zio Qwiic Loudness Sensor Master Awake");
Wire.begin(); //initialize I2C bus
Wire.setClock(400000); //Qwiic Scale is capable of running at 400kHz if desired
testForConnectivity();
// for (int thisReading = 0; thisReading < numReadings; thisReading++) {
// readings[thisReading] = 0;
// }
//Initialize BME280
//For I2C, enable the following and disable the SPI section
myBME280.settings.commInterface = I2C_MODE;
myBME280.settings.I2CAddress = 0x77;
myBME280.settings.runMode = 3; //Normal mode
myBME280.settings.tStandby = 0;
myBME280.settings.filter = 4;
myBME280.settings.tempOverSample = 5;
myBME280.settings.pressOverSample = 5;
myBME280.settings.humidOverSample = 5;
//Calling .begin() causes the settings to be loaded
delay(20); //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
byte id = myBME280.begin(); //Returns ID of 0x60 if successful
if (id != 0x60)
{
Serial.println("Problem with BME280");
}
else
{
Serial.println("BME280 online");
}
if (myScale.begin() == false)
{
Serial.println("Scale not detected. Please check wiring. Freezing...");
while (1);
}
Serial.println("Scale detected!");
readSystemSettings(); //Load zeroOffset and calibrationFactor from EEPROM
myScale.setSampleRate(NAU7802_SPS_320); //Increase to max sample rate
myScale.calibrateAFE(); //Re-cal analog front end when we change gain, sample rate, or channel
Serial.print("Zero offset: ");
Serial.println(myScale.getZeroOffset());
Serial.print("Calibration factor: ");
Serial.println(myScale.getCalibrationFactor());
}
void loop() {
get_value();
delay(100);
}
void get_value() {
// Check EEPROM to verify that the scale is calibrated
if(settingsDetected == false)
{
Serial.print("\tScale not calibrated. Press 'c'.");
}
//scale calibration / tare checks
if (Serial.available())
{
byte incoming = Serial.read();
if (incoming == 't') //Tare the scale
myScale.calculateZeroOffset();
else if (incoming == 'c') //Calibrate
{
calibrateScale();
}
}
unsigned long currentTime = millis();
myScale.powerUp();
Wire.beginTransmission(qwiicAddress);
Wire.write(COMMAND_GET_VALUE); // command for status
Wire.endTransmission(); // stop transmitting //this looks like it was essential.
Wire.requestFrom(qwiicAddress, 2); // request 1 bytes from slave device qwiicAddress
while (Wire.available()) { // slave may send less than requested
uint8_t ADC_VALUE_L = Wire.read();
uint8_t ADC_VALUE_H = Wire.read();
//lines are needed but I don't know why
ADC_VALUE=ADC_VALUE_H;
ADC_VALUE<<=8;
ADC_VALUE|=ADC_VALUE_L;
// read various sensors
ADC_total = ADC_total + ADC_VALUE;
CO2_total = CO2_total + (myCCS811.getCO2());
TEMP_total = TEMP_total + (myBME280.readTempF());
TVOC_total = TVOC_total + (myCCS811.getTVOC());
PRES_total = PRES_total + (myBME280.readFloatPressure());
ALT_total = ALT_total + (myBME280.readFloatAltitudeFeet());
H2O_total = H2O_total + (myBME280.readFloatHumidity());
WGT_total = WGT_total + myScale.getWeight();
readIndex = readIndex +1;
// if we're at the end of the array...
if (readIndex >= numReadings) {
// calculate the averages:
ADC_average = ADC_total / numReadings;
CO2_average = CO2_total / numReadings;
TEMP_average = TEMP_total / numReadings;
TVOC_average = TVOC_total / numReadings;
PRES_average = PRES_total / numReadings;
ALT_average = ALT_total / numReadings;
H2O_average = H2O_total / numReadings;
WGT_average = WGT_total / numReadings;
// Print function to print data to serial port
printData();
// Reset counters to 0
readIndex = 0;
ADC_total = 0;
CO2_total = 0;
TEMP_total = 0;
TVOC_total = 0;
PRES_total = 0;
ALT_total = 0;
H2O_total = 0;
WGT_total = 0;
}
delay(sketch_delay); // delay in between reads for stability
}
// uint16_t x=Wire.read();
}
// testForConnectivity() checks for an ACK from an Sensor. If no ACK
// program freezes and notifies user.
void testForConnectivity() {
Wire.beginTransmission(qwiicAddress);
//check here for an ACK from the slave, if no ACK don't allow change?
if (Wire.endTransmission() != 0) {
Serial.println("Check connections. No slave attached.");
while (1);
}
}
void printData()
{
Serial.print("\t Avg. ADC Value:\t\t");
Serial.print(ADC_average, DEC);
Serial.println();
Serial.print("\t Total ADC Value:\t\t");
Serial.print(ADC_total, DEC);
Serial.println();
Serial.println();
Serial.print("\t Avg. CO2 Value:\t\t");
Serial.print(CO2_average, DEC);
Serial.println();
Serial.print("\t Total CO2 Value:\t\t");
Serial.print(CO2_total, DEC);
Serial.println();
Serial.println();
Serial.print("\t Avg. Temp Value:\t\t");
Serial.print(TEMP_average, DEC);
Serial.println();
Serial.print("\t Total Temp Value:\t\t");
Serial.print(TEMP_total, DEC);
Serial.println();
Serial.println();
Serial.print("\t Avg. TVOC Value:\t\t");
Serial.print(TVOC_average, DEC);
Serial.println();
Serial.print("\t Total TVOC Value:\t\t");
Serial.print(TVOC_total, DEC);
Serial.println();
Serial.println();
Serial.print("\t Avg. Pressure Value:\t\t");
Serial.print(PRES_average, DEC);
Serial.println();
Serial.print("\t Total Pressure Value:\t\t");
Serial.print(PRES_total, DEC);
Serial.println();
Serial.println();
Serial.print("\t Avg. Humidity Value:\t\t");
Serial.print(H2O_average, DEC);
Serial.println();
Serial.print("\t Total Humidity Value:\t\t");
Serial.print(H2O_total, DEC);
Serial.println();
Serial.println();
Serial.print("\t Avg. Altitude Value:\t\t");
Serial.print(ALT_average, DEC);
Serial.println();
Serial.print("\t Total Altitude Value:\t\t");
Serial.print(ALT_total, DEC);
Serial.println();
Serial.println();
Serial.print("\t Avg. Weight Value:\t\t");
Serial.print(WGT_average, DEC);
Serial.println();
Serial.print("\t Total Weight Value:\t\t");
Serial.print(WGT_total, 3);
Serial.println();
Serial.println();
Serial.print("\t Number of Readings:\t\t");
Serial.print(numReadings, DEC);
Serial.println();
// output as CSV format for reading by linux box
Serial.println((String)ADC_average+","+CO2_average+","+TEMP_average+","+TVOC_average+","+PRES_average+","+H2O_average+","+ALT_average+","+WGT_average);
Serial.println();
Serial.println();
}
void printDriverError( CCS811Core::status errorCode )
{
switch ( errorCode )
{
case CCS811Core::SENSOR_SUCCESS:
Serial.print("SUCCESS");
break;
case CCS811Core::SENSOR_ID_ERROR:
Serial.print("ID_ERROR");
break;
case CCS811Core::SENSOR_I2C_ERROR:
Serial.print("I2C_ERROR");
break;
case CCS811Core::SENSOR_INTERNAL_ERROR:
Serial.print("INTERNAL_ERROR");
break;
case CCS811Core::SENSOR_GENERIC_ERROR:
Serial.print("GENERIC_ERROR");
break;
default:
Serial.print("Unspecified error.");
}
}
//Gives user the ability to set a known weight on the scale and calculate a calibration factor
void calibrateScale(void)
{
Serial.println();
Serial.println();
Serial.println(F("Scale calibration"));
Serial.println(F("Setup scale with no weight on it. Press a key when ready."));
while (Serial.available()) Serial.read(); //Clear anything in RX buffer
while (Serial.available() == 0) delay(1000); //Wait for user to press key
myScale.calculateZeroOffset(64); //Zero or Tare the scale. Average over 64 readings.
Serial.print(F("New zero offset: "));
Serial.println(myScale.getZeroOffset());
Serial.println(F("Place known weight on scale. Press a key when weight is in place and stable."));
while (Serial.available()) Serial.read(); //Clear anything in RX buffer
while (Serial.available() == 0) delay(1000); //Wait for user to press key
Serial.print(F("Please enter the weight, without units, currently sitting on the scale (for example '4.25'): "));
while (Serial.available()) Serial.read(); //Clear anything in RX buffer
while (Serial.available() == 0) delay(1000); //Wait for user to press key
//Read user input
float weightOnScale = Serial.parseFloat();
Serial.println();
myScale.calculateCalibrationFactor(weightOnScale, 64); //Tell the library how much weight is currently on it
Serial.print(F("New cal factor: "));
Serial.println(myScale.getCalibrationFactor(), 2);
Serial.print(F("New Scale Reading: "));
Serial.println(myScale.getWeight(), 2);
recordSystemSettings(); //Commit these values to EEPROM
}
void recordSystemSettings(void)
{
//Get various values from the library and commit them to NVM
EEPROM.put(LOCATION_CALIBRATION_FACTOR, myScale.getCalibrationFactor());
EEPROM.put(LOCATION_ZERO_OFFSET, myScale.getZeroOffset());
}
//Reads the current system settings from EEPROM
//If anything looks weird, reset setting to default value
void readSystemSettings(void)
{
float settingCalibrationFactor; //Value used to convert the load cell reading to lbs or kg
long settingZeroOffset; //Zero value that is found when scale is tared
//Look up the calibration factor
EEPROM.get(LOCATION_CALIBRATION_FACTOR, settingCalibrationFactor);
if (settingCalibrationFactor == 0xFFFFFFFF)
{
settingCalibrationFactor = 0; //Default to 0
EEPROM.put(LOCATION_CALIBRATION_FACTOR, settingCalibrationFactor);
}
//Look up the zero tare point
EEPROM.get(LOCATION_ZERO_OFFSET, settingZeroOffset);
if (settingZeroOffset == 0xFFFFFFFF)
{
settingZeroOffset = 1000L; //Default to 1000 so we don't get inf
EEPROM.put(LOCATION_ZERO_OFFSET, settingZeroOffset);
}
//Pass these values to the library
myScale.setCalibrationFactor(settingCalibrationFactor);
myScale.setZeroOffset(settingZeroOffset);
settingsDetected = true; //Assume for the moment that there are good cal values
if (settingCalibrationFactor < 0.1 || settingZeroOffset == 1000)
settingsDetected = false; //Defaults detected. Prompt user to cal scale.
}