ropg / heltec_esp32_lora_v3

Proper working Arduino library for the Heltec ESP32 LoRa v3 board, as well as for Wireless Stick v3 and Wireless Stick Lite v3. Uses RadioLib
MIT License
254 stars 12 forks source link

installation in platform.io #6

Open cibernox opened 3 months ago

cibernox commented 3 months ago

Hi! This may be me because I'm fairly new to IOT development, but I wanted to use this library on Platform.io instead of the arduino IDE, but it's not clear to me how to add it unofficial boards (if at all possible).

Can this library be installed on Platform.io?

ropg commented 3 months ago

Hey there! I'm sure it can be, but to be honest I've really only used other people's board setups in PlatformIO and never been customizing much there. It's on my list to figure that out and make it just as nice and "works out of the box" there as it is in the Arduino IDE. Tomorrow I'm getting the 2 x Wireless Stick Lite I ordered, but that should be minimal work, mostly just verifying that it's like I expect it is and adding a #define and a board definition, and then after that I might get to it.

aintgotnoname commented 3 months ago

My (humble) answer is Yes, but....

I've only been playing with PlatformIO/C++/VScode for a few months. Even though I sport old gray hairs, I don't consider myself an expert at this new fangled (and wonderful) stuff.

The library installs and is easily usable in single file projects. However, I had duplicated code blocks causing linker problems (even with the no instance macros) with includes in multiple cpp files. For me, it was easiest to duplicate the heltec.h file as a pure include (heltec_api.h) that just references/externs much of the original work. While not pure, this worked for me. I mention it only as an additional include file (and minor refactoring) may keep with the original intent (it just works), while providing api definitions for old foggies that need to include the library definitions throughout multiple files within a project.

Again, my thanks for the library. It saved me a lot of work doing exactly the same on my own.


[env:heltec_wifi_lora_32_V3]
platform = espressif32
board = heltec_wifi_lora_32_V3
framework = arduino
monitor_speed = 115200
upload_speed = 921600

board_build.mcu = esp32s3
board_build.f_cpu = 240000000L

lib_deps =
  ${libraries.pubsubclient}
  ${libraries.arduinojson}
  ;${libraries.arduinolog}
  ;${libraries.radiolib}
  ${libraries.heltec_wifi_kit_32_V3_unofficial}
  GPIO
  SPI
  EEPROM
  SERIAL
  WIFI

build_flags = 
 -DMQTT_MAX_PACKET_SIZE=1000
 -DCORE_DEBUG_LEVEL=0
 -DIOTWEBCONF_DEBUG_DISABLED=1
 -DARDUINOJSON_USE_LONG_LONG=1
 -DLoRaWAN_DEBUG_LEVEL=1
 -DWireless_Stick_V3=1
 -DREGION_US915=1
 -DHELTEC_WIRELESS_STICK=1

And my heltec_api.h : (essentially just function prototypes and defines). Worthy as a discussion, but not worthy as a solution.

/**
 * @file heltec_api.h
 * @brief Header file for the Heltec library.
 *
 * This file contains the definitions and declarations for the Heltec library.
 * The library provides functions for controlling the Heltec ESP32 LoRa V3
 * board, including LED brightness control, voltage measurement, deep sleep
 * mode, and more.
 */

#ifndef heltec_api_h
#define heltec_api_h

// 'PRG' Button
#define BUTTON    GPIO_NUM_0
// LED pin & PWM parameters
#define LED_PIN   GPIO_NUM_35
#define LED_FREQ  5000
#define LED_CHAN  0
#define LED_RES   8
// External power control
#define VEXT      GPIO_NUM_36
// Battery voltage measurement
#define VBAT_CTRL GPIO_NUM_37
#define VBAT_ADC  GPIO_NUM_1
// SPI pins
//#define SS        GPIO_NUM_8
//#define MOSI      GPIO_NUM_10
//#define MISO      GPIO_NUM_11
//#define SCK       GPIO_NUM_9
// Radio pins
#define DIO1      GPIO_NUM_14
//#define RST_LoRa  GPIO_NUM_12
//#define BUSY_LoRa GPIO_NUM_13
// Display pins
//#define SDA_OLED  GPIO_NUM_17
//#define SCL_OLED  GPIO_NUM_18
//#define RST_OLED  GPIO_NUM_21

#ifndef HELTEC_NO_RADIOLIB
  #include "RadioLib/RadioLib.h"
  // make sure the power off button works when using RADIOLIB_OR_HALT
  // (See RadioLib_convenience.h)
  #define RADIOLIB_DO_DURING_HALT heltec_delay(10)
  #include "RadioLib_convenience.h"
  String radiolib_result_string(const int16_t result);
#endif

#ifdef HELTEC_NO_DISPLAY
  #define HELTEC_NO_DISPLAY_INSTANCE
#else
  #include "display/SSD1306Wire.h"
#endif

//#include "HotButton.h"

#ifndef HELTEC_NO_RADIO_INSTANCE
  #ifndef HELTEC_NO_RADIOLIB
    extern SX1262 radio;
  #endif
#endif

// Don't you just hate it when battery percentages are wrong?
//
// I measured the actual voltage drop on a LiPo battery and these are the
// average voltages, expressed in 1/256'th steps between min_voltage and
// max_voltage for each 1/100 of the time it took to discharge the battery. The
// code for a telnet server that outputs battery voltage as CSV data is in
// examples, and a python script that outputs the constants below is in
// src/tools.
extern const float min_voltage;
extern const float max_voltage;
extern const uint8_t scaled_voltage[100];

/**
 * @class PrintSplitter
 * @brief A class that splits the output of the Print class to two different
 *        Print objects.
 *
 * The PrintSplitter class is used to split the output of the Print class to two
 * different Print objects. It overrides the write() function to write the data
 * to both Print objects.
 */
class PrintSplitter : public Print {
  public:
    PrintSplitter(Print &_a, Print &_b) : a(_a), b(_b) {}
    size_t write(uint8_t c) {
      a.write(c);
      return b.write(c);
    }
    size_t write(const char* str) {
      a.write(str);
      return b.write(str);
    }
  private:
    Print &a;
    Print &b;
};

  extern SSD1306Wire display;
  extern PrintSplitter both;

  // extern HotButton button;

/**
 * @brief Controls the LED brightness based on the given percentage.
 *
 * This function sets up the LED channel, frequency, and resolution, and then
 * adjusts the LED brightness based on the given percentage. If the percentage
 * is 0 or less, the LED pin is set as an input pin.
 *
 * @param percent The brightness percentage of the LED (0-100).
 */
void heltec_led(int percent);

/**
 * @brief Controls the VEXT pin to enable or disable external power.
 *
 * This function sets the VEXT pin as an output pin and sets its state based on
 * the given parameter. If the state is true, the VEXT pin is set to LOW to
 * enable external power. If the state is false, the VEXT pin is set to INPUT to
 * disable external power.
 *
 * @param state The state of the VEXT pin (true = enable, false = disable).
 */
void heltec_ve(bool state);

/**
 * @brief Measures the battery voltage.
 *
 * This function measures the battery voltage by controlling the VBAT_CTRL pin
 * and reading the analog value from the VBAT_ADC pin. The measured voltage is
 * then converted to a float value and returned.
 *
 * @return The battery voltage in volts.
 */
float heltec_vbat();

/**
 * @brief Puts the device into deep sleep mode.
 *
 * This function prepares the device for deep sleep mode by disconnecting from
 * WiFi, turning off the display, disabling external power, and turning off the
 * LED. It can also be configured to wake up after a certain number of seconds
 * using the optional parameter.
 *
 * @param seconds The number of seconds to sleep before waking up (default = 0).
 */
void heltec_deep_sleep(int seconds = 0);

/**
 * @brief Calculates the battery percentage based on the measured battery
 * voltage.
 *
 * This function calculates the battery percentage based on the measured battery
 * voltage. If the battery voltage is not provided as a parameter, it will be
 * measured using the heltec_vbat() function. The battery percentage is then
 * returned as an integer value.
 *
 * @param vbat The battery voltage in volts (default = -1).
 * @return The battery percentage (0-100).
 */
int heltec_battery_percent(float vbat = -1);

/**
 * @brief Checks if the device woke up from deep sleep due to button press.
 * 
 * @return True if the wake-up cause is a button press, false otherwise.
 */
bool heltec_wakeup_was_button();

/**
 * @brief Checks if the device woke up from deep sleep due to a timer.
 * 
 * This function checks if the device woke up from deep sleep due to a timer.
 * 
 * @return True if the wake-up cause is a timer interrupt, false otherwise.
 */
bool heltec_wakeup_was_timer();

/**
 * @brief Measures esp32 chip temperature
 * 
 * @return float with temperature in degrees celsius.
*/
float heltec_temperature();

/**
 * @brief Initializes the Heltec library.
 *
 * This function should be the first thing in setup() of your sketch. It
 * initializes the Heltec library by setting up serial port and display.
 */
void heltec_setup();

/**
 * @brief The main loop function for the Heltec library.
 *
 * This function should be called in loop() of the Arduino sketch. It updates
 * the state of the power button and implements long-press power off if used.
 */
void heltec_loop();

/**
 * @brief Delays the execution of the program for the specified number of
 *        milliseconds.
 *
 * This function delays the execution of the program for the specified number of
 * milliseconds. During the delay, it also calls the heltec_loop() function to
 * allow for the power off button to be checked.
 *
 * @param ms The number of milliseconds to delay.
 */
void heltec_delay(int ms);

#endif  // heltec_api_h