Skip to content

Instantly share code, notes, and snippets.

@bboyho
Last active February 16, 2024 19:42
Show Gist options
  • Save bboyho/1445543ab67858650a9171dc58b473b1 to your computer and use it in GitHub Desktop.
Save bboyho/1445543ab67858650a9171dc58b473b1 to your computer and use it in GitHub Desktop.
/******************************************************************************
Example 4 - Combined Soil Moisture Sensor Basic Readings and Qwiic OLED (0.91", 128x32)
This example reads the "moisture" levels from the Soil Moisture Sensor. The moisture
levels are the ADC values read by the little microcontroller on the sensor and these values
are gathered from the legs. The sensor readings can be read in the Arduino Serial Monitor
(115200 baud) or the Qwiic OLED. This code was written specifically for the 0.91", 128x32 verison.
Based on code written by NOA labs
Revised By: Elias Santistevan at SparkFun Electronics, 2/2024
Modified By: Ho Yun "Bobby" Chan at SparkFun Electronics, 2/2024
Products:
SparkFun Soil Moisture Sensor: https://www.sparkfun.com/products/22409
Qwiic Micro OLED (0.9", 128x32): https://www.sparkfun.com/products/17153
SparkFun code, firmware, and software is released under the MIT
License (http://opensource.org/licenses/MIT).
******************************************************************************/
#include <SparkFun_Qwiic_OLED.h> //http://librarymanager/All#SparkFun_Qwiic_Graphic_OLED
// The Qwiic OLED Arduino Library supports three different types of SparkFun boards. The demo uses the following
// defines to determine which device is being used. Uncomment the device being used for this demo.
// QwiicMicroOLED myOLED;
// QwiicTransparentOLED myOLED;
QwiicNarrowOLED myOLED;
// Fonts
#include <res/qw_fnt_5x7.h>
#include <res/qw_fnt_8x16.h>
//#include <res/qw_fnt_31x48.h> // too big for narrow OLED, so commenting out to save memory
#include <res/qw_fnt_7segment.h>
//#include <res/qw_fnt_largenum.h> // too big for narrow OLED, so commenting out to save memory
/* Commenting out. The code will set the font by directly pointing to the font. This is used as a reference.
// An array of fonts to loop over
QwiicFont *demoFonts[] = {
&QW_FONT_5X7,
&QW_FONT_8X16,
//&QW_FONT_31X48, //not used, commenting out
//&QW_FONT_LARGENUM, //not used, commenting out
&QW_FONT_7SEGMENT
};
*/
//#include <Wire.h> //commenting out since the Qwiic OLED Arduino Library alerady includes it
#define COMMAND_LED_OFF 0x00
#define COMMAND_LED_ON 0x01
#define COMMAND_GET_VALUE 0x05
#define COMMAND_NOTHING_NEW 0x99
int qwiicAddress = 0x28; //Default Address of Soil Moisture Sensor
void setup() {
Wire.begin();
Serial.begin(115200);
Serial.println("Example 4: SparkFun Soil Moisture Sensor Basic Readings on a Qwiic OLED (0.91 in, 128x32) ");
// Initalize the Qwiic OLED device and related graphics system
if (myOLED.begin() == false) {
Serial.println("Device begin failed. Freezing...");
while (true)
;
}
// Initalize the Qwiic Soil Moisture Sensor
if (!sensorBegin()) {
Serial.println("Could not communicate with the sensor, check that connections are solid or that you have the correct I2C address.");
while (1)
;
}
enableLed(true);
delay(500);
}
void loop() {
uint16_t soilMoistureValue = getMoistureLevels(); //values should range between 0 to 1023
//Clear display
myOLED.erase();
myOLED.setFont(&QW_FONT_5X7); //Set font
myOLED.setCursor(0, 0); //Set position
myOLED.print(" Soil Moisture Value ");
myOLED.setFont(&QW_FONT_7SEGMENT); //Set font
//myOLED.print("11111111111");
// Center Soil Moisture Sensor Value in the middle of the screen
// Set position of reading based on size of value and pixel size
// For the 7 segment Font, we used the font attributes (FONT_7SEG_WIDTH and FONT_7SEG_HEIGHT)
// defined in the Arduino Library => https://github.com/njh/SparkFun_Qwiic_OLED_Arduino_Library/blob/af4732ffbe022c1385b3effeb11802c54baaa36f/src/res/_fnt_7segment.h#L28
int width = 0;
if (soilMoistureValue >= 1000) {
width = 4 * FONT_7SEG_WIDTH;
} else if (soilMoistureValue < 1000 && soilMoistureValue >= 100) {
width = 3 * FONT_7SEG_WIDTH;
} else if (soilMoistureValue < 100 && soilMoistureValue >= 10) {
width = 2 * FONT_7SEG_WIDTH;
} else { //soilMoistureValue < 10
width = 1 * FONT_7SEG_WIDTH;
}
// if the string is wider than the screen, set x at 0, otherwise center text
int centerX = (width >= myOLED.getWidth() ? 0 : (myOLED.getWidth() - width) / 2);
Serial.println(centerX);
// (Starting y position - width minus string height / 2 ) + 8 . No need to chech height, 5x7 font fits everything
int centerY = ((myOLED.getHeight() - myOLED.getStringHeight(FONT_7SEG_HEIGHT)) / 2) + 8;
myOLED.setCursor(centerX, centerY); //Set position
myOLED.print(soilMoistureValue);
myOLED.display();
Serial.print("Soil Moisture Value: ");
Serial.println(soilMoistureValue);
enableLed(true);
delay(1000);
enableLed(false);
delay(1000);
}
/// @brief Gets the ADC value from the Soil Moisture Sensor
/// @return The 16 bit unsigned value read from the sensor.
uint16_t getMoistureLevels() {
uint16_t adcValue = 0;
Wire.beginTransmission(qwiicAddress);
Wire.write(COMMAND_GET_VALUE);
Wire.endTransmission();
Wire.requestFrom(qwiicAddress, (int)2);
while (Wire.available()) {
uint8_t ADC_VALUE_L = Wire.read();
uint8_t ADC_VALUE_H = Wire.read();
adcValue = ADC_VALUE_H << 8;
adcValue |= ADC_VALUE_L;
}
return adcValue;
}
/// @brief Turns the Soil Moisture Sensor's LED on or off.
/// @param on True turns it on and False turns it off.
void enableLed(bool on) {
Wire.beginTransmission(qwiicAddress);
if (on)
Wire.write(COMMAND_LED_ON);
if (!on)
Wire.write(COMMAND_LED_OFF);
Wire.endTransmission();
}
/// @brief Does a quick I2C check to see if the Soil Moisture sensor responds.
/// @return Returns true on successful communication and false otherwise.
bool sensorBegin() {
Wire.beginTransmission(qwiicAddress);
delay(10);
if (Wire.endTransmission() != 0) {
return false;
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment