xinmeng_wit 发表于 2022-5-3 19:01

【平头哥RVB2601创意应用开发】6、网络天气时钟草版

<p><span style="font-family:Arial;"><span style="font-size:20px;">一、说明</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">网络天气时钟基本功能:</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">1、RTC实时时钟显示,并上电自动对时</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">2、实时天气信息显示</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">3、未来天气预报(计划是未来3天的天气预报,发现免费版本的YY天气只能预报当天和第二天的天气&#128517;)</span></span></p>

<p><span style="font-family:Arial;"><span style="font-size:16px;">其实功能还是蛮简单的,就是wifi联网和NTP搞了搞了时间比较长,NTP目前虽然能对时,但是感觉还是不完美。</span></span></p>

<p>&nbsp;</p>

<p><span style="font-family:Arial;"><span style="font-size:20px;">二、用到的软件模块/开源库</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">1、u8g2开源图形库,用于显示</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">2、cJSON开源库,用于json格式的数据解析</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">3、MulitButton开源库,用于按键的操作</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">4、OS层面,使用了软件定时器来周期获取和显示时间,周期是1s;</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">使用了消息队列实现跨任务通讯,传输天气数据;</span></span></p>

<p><span style="font-family:Arial;"><span style="font-size:16px;">使用了事件来做任务同步。</span></span></p>

<p>&nbsp;</p>

<p><span style="font-family:Arial;"><span style="font-size:20px;">三、关键功能说明</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">1、NTP网络对时</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">关于NTP的问题,之前论坛几位大佬已经写了避坑手册,按照他们的帖子配置基本是没有问题的。</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">ntp的组件我用的7.4.6的版本,7.4.3版本我怎么弄都过不了。</span></span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">目前的版本有时候要几次尝试才能成功,我自己代码里面做了重试机制。</span></span></p>

<p><span style="font-family:Arial;"><span style="font-size:16px;">ntp对时完成后设置事件,让GUI任务区获取时间进行显示:</span></span></p>

<pre>
<code class="language-cpp">static void network_event(uint32_t event_id, const void *param, void *context)
{
    switch(event_id) {
    case EVENT_NETMGR_GOT_IP:
      LOGD(TAG, "net got ip");
                do
                {
                        ntp_status = ntp_sync_time(NULL);
                }while(ntp_status != 0);
                /*设置事件标志(0x00000001), 或操作*/
                aos_event_set(&amp;ntp_complete_event, EVENT_FLAG_1, AOS_EVENT_OR);               
                //cjson_test ();
      break;
    case EVENT_NETMGR_NET_DISCON:
      LOGD(TAG, "net disconnect");
      break;
    }

    /*do exception process */
    app_exception_event(event_id);
}</code></pre>

<p><span style="font-family:Arial;">2、GUI任务</span></p>

<p><span style="font-size:16px;"><span style="font-family:Arial;">GUI任务主要是接收消息队列的消息,根据消息类型进行显示不同的内容</span></span></p>

<p><span style="font-family:Arial;"><span style="font-size:16px;">主体如下:</span></span></p>

<pre>
<code class="language-cpp">    while (1) {
                //button_test();
                button_ticks();
                //check data receive
                if(0 != aos_queue_is_valid(&amp;queue_weather))
                {
                        if(0 == aos_queue_recv(&amp;queue_weather, 5, queue_msg, &amp;quene_size))
                        {
                                if(display_page == 1)//显示时钟
                                {
                                        rtc_display_control(queue_msg);
                                }
                                else if(display_page == 2)//显示实时天气
                                {
                                        weather_real_time_display(queue_msg);
                                }
                                else if((display_page == 3) || (display_page == 4))//显示预报天气
                                {
                                        weather_forecast_display(queue_msg);
                                }
                               
                        }                       
                }
    }</code></pre>

<p><span style="font-size:16px;"><span style="font-family:Arial;">3、按键</span></span></p>

<p><span style="font-family:Arial;"><span style="font-size:16px;">按键的操作移植了MultiButton库,只用到了板载两个按键的单击事件,一个上翻页一个下翻页:</span></span></p>

<pre>
<code class="language-cpp">//按键事件的callback
static void BTN1_SINGLE_Click_Handler(void* btn)
{
        char temp;
        display_page++;
        if(display_page &gt; 4)
        {
                display_page = 1;
        }
        if(display_page == 1)
        {
                temp = 50;//切到第一屏
                temp = '\0';
                if(0 != aos_queue_send(&amp;queue_weather, temp, sizeof(temp)))
                {
                        printf("send display_page error--&gt;button2 singel click\n");
                }
        }       
        else if(display_page == 2)//实时天气获取与显示
        {
                quest_weather();
        }
        else if((display_page &gt;= 3) &amp;&amp; (display_page &lt;=4 ))//未来某天天气预报
        {
                quest_weather_forecast();
        }       
}

//按键事件的callback
static void BTN2_SINGLE_Click_Handler(void* btn)
{
        char temp;
       
        if(display_page &gt; 1)
        {
                display_page--;
                if(display_page == 1)
                {
                        temp = 50;//切到第一屏
                        temp = '\0';
                        if(0 != aos_queue_send(&amp;queue_weather, temp, sizeof(temp)))
                        {
                                printf("send display_page error--&gt;button2 singel click\n");
                        }
                }
                else if(display_page == 2)//实时天气获取与显示
                {
                        quest_weather();
                }
                else if((display_page &gt;= 3) &amp;&amp; (display_page &lt;=4 ))//未来某天天气预报
                {
                        quest_weather_forecast();
        }                       
        }
       
}</code></pre>

<p><span style="font-family:Arial;"><span style="font-size:20px;">四、效果展示</span></span></p>

<p><span style="font-family:Arial;"><iframe allowfullscreen="true" frameborder="0" height="450" src="//player.bilibili.com/player.html?bvid=1AL4y1c7r8&amp;page=1" style="background:#eee;margin-bottom:10px;" width="700"></iframe></span><br />
&nbsp;</p>

lugl4313820 发表于 2022-5-3 19:45

<p>有进展呀,恭喜恭喜!</p>

xinmeng_wit 发表于 2022-5-3 20:13

lugl4313820 发表于 2022-5-3 19:45
有进展呀,恭喜恭喜!

<p>谢谢,还任重道远{:1_144:}</p>

lugl4313820 发表于 2022-5-3 20:22

<p>能不能发你的NTP例子给我学习一下呀。</p>

xinmeng_wit 发表于 2022-5-4 09:20

lugl4313820 发表于 2022-5-3 20:22
能不能发你的NTP例子给我学习一下呀。

<p>我的改动很简单,就两步操作:</p>

<p>1、w800_api.c里修改函数:int w800_connect_remote(int id, net_conn_e type, char *srvname, uint16_t port)</p>

<p>具体:</p>

<p>int w800_connect_remote(int id, net_conn_e type, char *srvname, uint16_t port)<br />
{<br />
&nbsp;&nbsp;&nbsp; int ret = -1;<br />
&nbsp;&nbsp;&nbsp; int ret_id;<br />
&nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp; &nbsp;uint16_t local_port = 1024;</p>

<p>&nbsp;&nbsp;&nbsp; if (g_net_status &lt; NET_STATUS_GOTIP) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOGE(TAG, &quot;net status error\n&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br />
&nbsp;&nbsp;&nbsp; }</p>

<p>&nbsp;&nbsp;&nbsp; aos_mutex_lock(&amp;g_cmd_mutex, AOS_WAIT_FOREVER);</p>

<p>&nbsp;&nbsp;&nbsp; atparser_clr_buf(g_atparser_uservice_t);</p>

<p>&nbsp;&nbsp;&nbsp; switch (type) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case NET_TYPE_TCP_SERVER:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* TCP Server can NOT ignore lport */<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case NET_TYPE_UDP_UNICAST:<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ret = atparser_send(g_atparser_uservice_t, &quot;AT+CIPSTART=%d,%s,%s,%d,%d&quot;, id, &quot;udp_unicast&quot;, srvname, port,local_port);<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;case NET_TYPE_TCP_CLIENT:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = atparser_send(g_atparser_uservice_t, &quot;AT+CIPSTART=%d,%s,%s,%d&quot;, id, &quot;tcp_client&quot;, srvname, port);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOGE(TAG, &quot;type=%d err!&quot;, type);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;</p>

<p>&nbsp;&nbsp;&nbsp; }</p>

<p>&nbsp;&nbsp;&nbsp; if (ret == 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = -1;</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((atparser_recv(g_atparser_uservice_t, &quot;OK\n&quot;) == 0) \<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; (atparser_recv(g_atparser_uservice_t, &quot;+EVENT=CONNECT,%d\n&quot;, &amp;ret_id) == 0)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ret_id == id) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }</p>

<p>&nbsp;&nbsp;&nbsp; atparser_cmd_exit(g_atparser_uservice_t);</p>

<p>&nbsp;&nbsp;&nbsp; aos_mutex_unlock(&amp;g_cmd_mutex);</p>

<p>&nbsp;&nbsp;&nbsp; return ret;<br />
}</p>

<p>&nbsp;</p>

<p>2、ntp组件使用7.4.6的版本</p>

<p></p>

<p>以上两个操作以后,ntp就能获取到正确的时间了。</p>

lugl4313820 发表于 2022-5-4 15:20

xinmeng_wit 发表于 2022-5-4 09:20
我的改动很简单,就两步操作:

1、w800_api.c里修改函数:int w800_connect_remote(int id, net_conn_e ...

<p>非常感谢,我回头试试。</p>

ylyfxzsx 发表于 2022-5-7 13:46

<p>哎哟喂,这个做的好,可比我做的强多了,做个上位机支持输入保存WIFISSID和密码,支持自定义输入NTPIP地址,完美了</p>

xinmeng_wit 发表于 2022-5-7 18:13

ylyfxzsx 发表于 2022-5-7 13:46
哎哟喂,这个做的好,可比我做的强多了,做个上位机支持输入保存WIFISSID和密码,支持自定义输入NTPIP地址 ...

<p>建议非常好,确实可以有{:1_144:}</p>

梦溪开物 发表于 2022-5-11 15:41

<p>对于需要认证的网络,能使用RVB2601的wifi联网吗?</p>
页: [1]
查看完整版本: 【平头哥RVB2601创意应用开发】6、网络天气时钟草版