honey_the_codewitch

weather_clock main

Jun 12th, 2022 (edited)
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.02 KB | None | 0 0
  1. #include <Arduino.h>
  2. #include <WiFi.h>
  3. #include <WiFiMulti.h>
  4.  
  5. #include <gfx_cpp14.hpp>
  6. #include <ili9341.hpp>
  7. #include <tft_io.hpp>
  8. #include <telegrama.hpp>
  9. #include <ip_loc.hpp>
  10. #include <ntp_time.hpp>
  11. #include <open_weather.hpp>
  12. using namespace arduino;
  13. using namespace gfx;
  14.  
  15. // wifi
  16. constexpr static const char* ssid = "SSID";
  17. constexpr static const char* password = "password";
  18.  
  19. // NTP server
  20.  
  21. constexpr static const char* ntp_server = "time.nist.gov";
  22.  
  23. // synchronize with NTP every 60 seconds
  24. constexpr static const int clock_sync_seconds = 60;
  25.  
  26. constexpr static const size16 clock_size = {120, 120};
  27.  
  28. constexpr static const uint8_t spi_host = VSPI;
  29. constexpr static const int8_t lcd_pin_bl = 32;
  30. constexpr static const int8_t lcd_pin_dc = 27;
  31. constexpr static const int8_t lcd_pin_cs = 14;
  32. constexpr static const int8_t spi_pin_mosi = 23;
  33. constexpr static const int8_t spi_pin_clk = 18;
  34. constexpr static const int8_t lcd_pin_rst = 33;
  35. constexpr static const int8_t spi_pin_miso = 19;
  36.  
  37. using bus_t = tft_spi_ex<spi_host,
  38.                         lcd_pin_cs,
  39.                         spi_pin_mosi,
  40.                         spi_pin_miso,
  41.                         spi_pin_clk,
  42.                         SPI_MODE0,
  43.                         false,
  44.                         320 * 240 * 2 + 8, 2>;
  45. using lcd_t = ili9342c<lcd_pin_dc,
  46.                       lcd_pin_rst,
  47.                       lcd_pin_bl,
  48.                       bus_t,
  49.                       1,
  50.                       true,
  51.                       400,
  52.                       200>;
  53. using color_t = color<typename lcd_t::pixel_type>;
  54.  
  55. lcd_t lcd;
  56.  
  57. template <typename Destination>
  58. void draw_clock(Destination& dst, tm& time, const ssize16& size) {
  59.     using view_t = viewport<Destination>;
  60.     srect16 b = size.bounds().normalize();
  61.     uint16_t w = min(b.width(), b.height());
  62.    
  63.     float txt_scale = Telegrama_otf.scale(w/10);
  64.     char* sz = asctime(&time);
  65.     *(sz+3)=0;
  66.     draw::text(dst,
  67.             dst.bounds(),
  68.             spoint16::zero(),
  69.             sz,
  70.             Telegrama_otf,
  71.             txt_scale,
  72.             color<typename Destination::pixel_type>::black);
  73.     sz+=4;
  74.     *(sz+6)='\0';
  75.  
  76.     ssize16 tsz = Telegrama_otf.measure_text(ssize16::max(),spoint16::zero(),sz,txt_scale);
  77.     draw::text(dst,
  78.             dst.bounds().offset(dst.dimensions().width-tsz.width-1,0).crop(dst.bounds()),
  79.             spoint16::zero(),
  80.             sz,
  81.             Telegrama_otf,
  82.             txt_scale,
  83.             color<typename Destination::pixel_type>::black);
  84.  
  85.     srect16 sr(0, 0, w / 16, w / 5);
  86.     sr.center_horizontal_inplace(b);
  87.     view_t view(dst);
  88.     view.center(spoint16(w / 2, w / 2));
  89.     static const float rot_step = 360.0/6.0;
  90.     for (float rot = 0; rot < 360; rot += rot_step) {
  91.         view.rotation(rot);
  92.         spoint16 marker_points[] = {
  93.             view.translate(spoint16(sr.x1, sr.y1)),
  94.             view.translate(spoint16(sr.x2, sr.y1)),
  95.             view.translate(spoint16(sr.x2, sr.y2)),
  96.             view.translate(spoint16(sr.x1, sr.y2))};
  97.         spath16 marker_path(4, marker_points);
  98.         draw::filled_polygon(dst, marker_path,
  99.           color<typename Destination::pixel_type>::gray);
  100.     }
  101.     sr = srect16(0, 0, w / 16, w / 2);
  102.     sr.center_horizontal_inplace(b);
  103.     view.rotation((time.tm_sec / 60.0) * 360.0);
  104.     spoint16 second_points[] = {
  105.         view.translate(spoint16(sr.x1, sr.y1)),
  106.         view.translate(spoint16(sr.x2, sr.y1)),
  107.         view.translate(spoint16(sr.x2, sr.y2)),
  108.         view.translate(spoint16(sr.x1, sr.y2))};
  109.     spath16 second_path(4, second_points);
  110.  
  111.     view.rotation((time.tm_min / 60.0) * 360.0);
  112.     spoint16 minute_points[] = {
  113.         view.translate(spoint16(sr.x1, sr.y1)),
  114.         view.translate(spoint16(sr.x2, sr.y1)),
  115.         view.translate(spoint16(sr.x2, sr.y2)),
  116.         view.translate(spoint16(sr.x1, sr.y2))};
  117.     spath16 minute_path(4, minute_points);
  118.  
  119.     sr.y1 += w / 8;
  120.     view.rotation(((time.tm_hour%12) / 12.0) * 360.0);
  121.     spoint16 hour_points[] = {
  122.         view.translate(spoint16(sr.x1, sr.y1)),
  123.         view.translate(spoint16(sr.x2, sr.y1)),
  124.         view.translate(spoint16(sr.x2, sr.y2)),
  125.         view.translate(spoint16(sr.x1, sr.y2))};
  126.     spath16 hour_path(4, hour_points);
  127.  
  128.     draw::filled_polygon(dst,
  129.                         minute_path,
  130.                         color<typename Destination::pixel_type>::black);
  131.  
  132.     draw::filled_polygon(dst,
  133.                         hour_path,
  134.                         color<typename Destination::pixel_type>::black);
  135.  
  136.     draw::filled_polygon(dst,
  137.                         second_path,
  138.                         color<typename Destination::pixel_type>::red);
  139. }
  140.  
  141. uint32_t update_ts;
  142. uint32_t sync_count;
  143. time_t current_time;
  144. srect16 clock_rect;
  145. ntp_time ntp;
  146. IPAddress ntp_ip;
  147. float latitude;
  148. float longitude;
  149. char city[128];
  150. char region[128];
  151. long utc_offset;
  152. open_weather_info weather_info;
  153. using clock_bmp_t = bitmap<typename lcd_t::pixel_type>;
  154. uint8_t clock_bmp_buf[clock_bmp_t::sizeof_buffer(clock_size)];
  155. clock_bmp_t clock_bmp(clock_size, clock_bmp_buf);
  156. void setup() {
  157.     Serial.begin(115200);
  158.     lcd.fill(lcd.bounds(),color_t::white);
  159.     Serial.print("Connecting");
  160.     WiFi.begin(ssid, password);
  161.     while (!WiFi.isConnected()) {
  162.         Serial.print(".");
  163.         delay(1000);
  164.     }
  165.     Serial.println();
  166.     Serial.println("Connected");
  167.     clock_rect = srect16(spoint16::zero(), (ssize16)clock_size);
  168.     clock_rect.offset_inplace(lcd.dimensions().width-clock_size.width ,lcd.dimensions().height-clock_size.height);
  169.     sync_count = clock_sync_seconds;
  170.     WiFi.hostByName(ntp_server,ntp_ip);
  171.     ntp.begin_request(ntp_ip);
  172.     while(ntp.requesting()) {
  173.         ntp.update();
  174.     }
  175.     if(!ntp.request_received()) {
  176.         Serial.println("Unable to retrieve time");
  177.         while (true);
  178.     }
  179.     ip_loc::fetch(&latitude,&longitude,&utc_offset,region,128,city,128);
  180.    
  181.     open_weather::fetch(latitude,longitude,&weather_info);
  182.     Serial.println(weather_info.city);
  183.     current_time = utc_offset+ntp.request_result();
  184.     update_ts = millis();
  185. }
  186.  
  187. void loop() {
  188.     ntp.update();
  189.     if(ntp.request_received()) {
  190.         Serial.println("Request received");
  191.         current_time = utc_offset+ntp.request_result();
  192.     }
  193.     uint32_t ms = millis();
  194.     if (ms - update_ts >= 1000) {
  195.         update_ts = ms;
  196.         ++current_time;
  197.         tm* t = localtime(&current_time);
  198.         //Serial.println(asctime(t));
  199.         draw::wait_all_async(lcd);
  200.         draw::filled_rectangle(clock_bmp,
  201.                               clock_size.bounds(),
  202.                               color_t::white);
  203.         draw_clock(clock_bmp, *t, (ssize16)clock_size);
  204.         draw::bitmap_async(lcd,
  205.                           clock_rect,
  206.                           clock_bmp,
  207.                           clock_bmp.bounds());
  208.         if (0 == --sync_count) {
  209.             sync_count = clock_sync_seconds;
  210.             ntp.begin_request(ntp_ip);
  211.         }
  212.     }
  213. }
Add Comment
Please, Sign In to add comment