Advertisement
Guest User

Untitled

a guest
Jun 17th, 2024
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.48 KB | None | 0 0
  1. #include <driver/rtc_io.h>
  2. #include <esp_sleep.h>
  3. #include "driver/ledc.h"
  4. #include "soc/rtc_cntl_reg.h"
  5. #include "soc/rtc.h"
  6.  
  7. //==========================================
  8. // SETTINGS
  9.  
  10. // SETUP YOUR PINS
  11.  
  12. // Define the GPIO pin for the mosfets switching the motor
  13. const int mosfetPin = 3;
  14.  
  15. // Define the Analog pin for the voltage sensor
  16. const int voltagePin = 0;
  17.  
  18. // Define the voltage threshold where the device will save a bit of power by vibrating less.
  19. // For when you have long cloudy autumns and the solar panel is not making enough power.
  20. const float voltageThreshold = 10.8;
  21.  
  22. // Short buzz length
  23. const int shortBuzz = 1000; //ms
  24.  
  25. // Long buzz length
  26. const int longBuzz = 3000; //ms
  27.  
  28. // Define the voltage divider resistor values (R1 and R2 in ohms)
  29. // If you have used just two resistors you already know.
  30. // If you purchased a sensor module chances are the below is correct
  31. const float R1 = 30000.0;  // 30k ohms
  32. const float R2 = 7500.0;  // 7.5k ohms
  33.  
  34. //ESPs and Arduinos measure voltage rather inaccurate, with up-to 10% error.
  35. //Check the voltage in test mode and compensate here if it is off.
  36. float actualVoltage1 = 10.0;
  37. float measuredVoltage1 = 10.86;  // Replace with your measured voltage
  38. float actualVoltage2 = 12.6;
  39. float measuredVoltage2 = 13.83;  // Replace with your measured voltage
  40.  
  41. // Boolean to enable/disable serial debug
  42. bool enableDebug = true;
  43.  
  44. // Test mode - in testmode the ESP will not go into deep sleep so you can read the serial messages.
  45. // In test mode the timeout is 1/10th of the real timeout, for example instead of 36sec it is 3.6sec
  46. bool testMode = false;
  47.  
  48. // Motor max speed - Define the max speed of the motor on the range of 0-8191
  49. // 8191 is 100% duty cycle for 13-bit resolution
  50. // With some motors slower vibration is more effective as high speed makes it smoother
  51.  
  52. const int maxSpeed = 5000;
  53.  
  54. // END OF SETTINGS
  55. //=========================================
  56.  
  57. // Motor PWM settings, ideally don't change it
  58. #define LEDC_TIMER              LEDC_TIMER_0
  59. #define LEDC_MODE               LEDC_LOW_SPEED_MODE
  60. #define LEDC_OUTPUT_IO          mosfetPin // Define the output GPIO
  61. #define LEDC_CHANNEL            LEDC_CHANNEL_0
  62. #define LEDC_DUTY_RES           LEDC_TIMER_13_BIT // Set duty resolution to 13 bits
  63. #define LEDC_DUTY               maxSpeed // Set duty cycle
  64. #define LEDC_FREQUENCY          (4000) // Frequency in Hertz. Set frequency at 4 kHz
  65.  
  66. void setup() {
  67.   if (enableDebug) {
  68.     Serial.begin(9600);  // Initialize serial communication for debugging
  69.   }
  70.  
  71.   // Initialize the MOSFET pin
  72.   pinMode(mosfetPin, OUTPUT);
  73.   digitalWrite(mosfetPin, LOW);  // Ensure the MOSFET is off initially
  74.  
  75.   // Initialize the voltage pin
  76.   pinMode(voltagePin, INPUT);
  77.  
  78.   // Seed the random number generator with a unique value
  79.   randomSeed(esp_random());
  80.  
  81.     // Disable deep sleep hold on the MOSFET pin if previously enabled
  82.   gpio_deep_sleep_hold_dis();
  83. }
  84.  
  85. // LEDC config to create PWM
  86. void ledc_init() {
  87.     ledc_timer_config_t ledc_timer = {
  88.         .speed_mode       = LEDC_MODE,
  89.         .duty_resolution  = LEDC_DUTY_RES,
  90.         .timer_num        = LEDC_TIMER,
  91.         .freq_hz          = LEDC_FREQUENCY,  // Set output frequency at 4 kHz
  92.         .clk_cfg          = LEDC_AUTO_CLK
  93.     };
  94.     ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
  95.  
  96.     // Prepare and then apply the LEDC PWM channel configuration
  97.     ledc_channel_config_t ledc_channel = {
  98.         .gpio_num       = LEDC_OUTPUT_IO,
  99.         .speed_mode     = LEDC_MODE,
  100.         .channel        = LEDC_CHANNEL,
  101.         .intr_type      = LEDC_INTR_DISABLE,
  102.         .timer_sel      = LEDC_TIMER,
  103.         .duty           = 0, // Set duty to 0%
  104.         .hpoint         = 0
  105.     };
  106.     ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
  107. }
  108.  
  109. //Setup voltage read compensation
  110. float calculateCalibrationFactor(float actualVoltage1, float measuredVoltage1, float actualVoltage2, float measuredVoltage2) {
  111.   float factor1 = actualVoltage1 / measuredVoltage1;
  112.   float factor2 = actualVoltage2 / measuredVoltage2;
  113.   float calibrationFactor = (factor1 + factor2) / 2;
  114.   return calibrationFactor;
  115. }
  116.  
  117. float readVoltage(float calibrationFactor) {
  118.   int analogValue = analogRead(voltagePin);
  119.   float voltage = analogValue * (3.3 / 4095.0);  // Convert analog reading to voltage
  120.   float inputVoltage = voltage * ((R1 + R2) / R2);  // Calculate the input voltage
  121.   float calibratedVoltage = inputVoltage * calibrationFactor;  // Apply calibration factor
  122.   return calibratedVoltage;
  123. }
  124.  
  125. void setMosfet(bool state) {
  126.   ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, state ? LEDC_DUTY : 0));
  127.   ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
  128. }
  129.  
  130. // Generate a random time between 30 and 60 seconds
  131. uint32_t sleepTime = 30 + esp_random() % 31;  // Random time between 30 and 60 seconds
  132.  
  133. void goToSleep() {
  134.   if (enableDebug) {
  135.     Serial.println("Going to sleep for: ");
  136.     Serial.print(sleepTime);
  137.     Serial.print(" seconds.");
  138.     }
  139.  
  140.   // Enable deep sleep hold on the MOSFET pin
  141.   gpio_deep_sleep_hold_en();
  142.  
  143.   if (testMode == true) {
  144.     //  In sleep mode we will just wait for a shorter timeout
  145.     delay(sleepTime * 100);
  146.   } else {
  147.     // Convert sleep time to microseconds and set up deep sleep
  148.     esp_sleep_enable_timer_wakeup(sleepTime * 1000000);
  149.     esp_deep_sleep_start();
  150.     }
  151. }
  152.  
  153. void loop() {
  154.   float calibrationFactor = calculateCalibrationFactor(actualVoltage1, measuredVoltage1, actualVoltage2, measuredVoltage2);
  155.   float voltage = readVoltage(calibrationFactor);
  156.     if (enableDebug) {
  157.   Serial.println("Calibration Factor: " + String(calibrationFactor));
  158.   Serial.println("Voltage: " + String(voltage));
  159.     }
  160.  
  161.   ledc_init();
  162.  
  163.   if (voltage < voltageThreshold) {
  164.       if (enableDebug) {
  165.         Serial.println("Voltage low - Short buzz");
  166.       }
  167.     for (int i = 0; i < 2; i++) {
  168.       setMosfet(true);
  169.       delay(shortBuzz);
  170.       setMosfet(false);
  171.       delay(shortBuzz);
  172.     }
  173.     gpio_hold_en(static_cast<gpio_num_t>(mosfetPin));
  174.     // Initiate deep sleep
  175.     goToSleep();
  176.  
  177.   } else {
  178.     // Short buzzes
  179.           if (enableDebug) {
  180.         Serial.println("Voltage OK - Normal buzz sequence.");
  181.       }
  182.     for (int i = 0; i < 3; i++) {
  183.       setMosfet(true);
  184.       delay(shortBuzz);
  185.       setMosfet(false);
  186.       delay(shortBuzz);
  187.     }
  188.  
  189.     setMosfet(true);
  190.     delay(longBuzz);
  191.     setMosfet(false);
  192.     gpio_hold_en(static_cast<gpio_num_t>(mosfetPin));
  193.     // Initiate deep sleep
  194.     goToSleep();
  195.   }
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement