I had to face several "difficulties":
- my solar tracker is intended to be used as a mobile device. But when moving your location moves also and thus the solar angles computation may drift a little. GPS coordinates should be updated into the ESP32 board whenever you change location. Particularly when the panel is used into a camper van...
- my solar tracker firmware needed Wifi to get the time over ntp server... This wasn't a good idea for a camper van (although it could work using your smartphone as a hotspot... but not really practical).
I had thus to find a way to overcome these issues...
I already had an Android App to help position the panel face to the sun. My ESP32 has also Bluetooth Low Energy... Seemed simple to add a BLE connection between phone and ESP32 to communicate the time and the location to the board.
This is exactly what I did, but it wasn't as simple as expected !
My specs were:
- avoid any "binding process" between phone and ESP32. Everything should be fully automatic
- try to connect to wifi on ESP32 and get the time over NTP. This shouldn' be a blocking process in case of a noWifi area
- allow BLE connection on the ESP32 while broadcasting (notifying) over BLE
- allow the time and position to be sent from phone when BLE is connected
- keep the BLE connection open while the Android App is running, go to deepsleep as soon as possible to save energy on the ESP32 board
- keep the nice feature of calibrating the panel position to a fast and easy start up on any new location at any time
- go on working on internal RTC clock if no wifi or no BLE link is available
Here is the result, with an extremely simple operationnal procedure:
- launch the companion App and position the panel as explained into this log
- when the panel is properly facing the sun, simply push the reset button of the ESP32 board
- quit the App
That's it !
I moved the phone to track the sun and at the end of the video I pushed the reset button of the ESP32.
Have a look at the bottom of this screen to see the automatic handshake between phone and board.
Several tricks are used to allow this simple behavior :
ESP32 allows to detect the boot condition. I did detect if it is a "reset boot" or not (deepsleep in this case).
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD :
Serial.println("Wakeup caused by touchpad");
touchWake = true;
break;
case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
default :
Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
resetWake = true;
break;
}
If it is a reset boot, then I do try to establish the Bluetooth link and wait 10s for it. If not (deepsleep boot) I simply try to get ntp time and if it fails I do use the RTC clock.
Be aware that RTC clock is not very accurate... So it will be a good idea, from time to time, to resync the time either with a permament Wifi connection or with the smartphone. With only the RTC internal clock you could expect several seconds of drift per day. This will not be an issue for our application as time is only used to point the panel to the sun...a few degrees of misalignement wouldn't affect too much the sun harvesting process.
Here is what says Expressif 's documentation :
ESP32 uses two hardware timers for the purpose of keeping system time. System time can be kept by using either one or both of the hardware timers depending on the application’s purpose and accuracy requirements for system time. The two hardware timers are:
- RTC timer: This timer allows time keeping in various sleep modes, and can also persist time keeping across any resets (with the exception of power-on resets which reset the RTC timer). The frequency deviation depends on the RTC Timer Clock Sources and affects the accuracy only in sleep modes, in which case the time will be measured at 6.6667 μs resolution.
- High-resolution timer: This timer is not available in sleep modes and will not persist over a reset, but has greater accuracy. The timer uses the APB_CLK clock source (typically 80 MHz), which has a frequency deviation of less than ±10 ppm. Time will be measured at 1 μs resolution.
Here is how the time is computed from the last saved value (hours, minutes, seconds et tvsec) and knowing the seconds elapsed since reboot (current_time.tv_sec) :
else if (!resetWake)
{
Serial.println("time from RTC :");
struct timeval current_time;
gettimeofday(¤t_time, NULL);
Serial.printf("seconds : %ld\nmicro seconds : %ld", current_time.tv_sec, current_time.tv_usec);
int sec = seconds - tvsec + current_time.tv_sec ;
sec = hours * 3600 + minutes * 60 + sec;
int ss = sec % 60;
sec = sec / 60;
int mm = sec % 60;
sec = sec / 60;
int hh = sec % 24;
int dd = days + sec / 24;
//set time manually (hr, min, sec, day, mo, yr)
setTime(hh, mm, ss, dd, months, years);
Serial.print("\ntime: ");
display_time();
}
Finally if the reset button has been pressed, we use this information to avoid moving the panel (supposed to be pointing to the sun) and go directly into deepsleep.
if (resetWake == true) //reset was done. Calibration of panel is acquired. Don't move
{
Serial.println("calibration of panel done, no motion and goto to sleep");
stepsToMoveEl = 0;
stepsToMoveAz = 0;
}
I forgot to mention that the "three dots menus" on top right of the App allows to send Wifi Credentials to your ESP32 board when you are close to a wifi router.
Afterwhat the process will remain fully automatic: a wake up every ten minutes, try to get the ntp time and move the panel accordingly to sun position.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.