<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=4&amp;t=22075&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2019-04-30T14:53:53+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=22075&amp;mode</id>
<entry>
<author><name><![CDATA[WoodPaker]]></name></author>
<updated>2019-04-30T14:53:53+01:00</updated>
<published>2019-04-30T14:53:53+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22075&amp;p=218600#p218600</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22075&amp;p=218600#p218600"/>
<title type="html"><![CDATA[Re: Menu na LCD 2 x 16]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22075&amp;p=218600#p218600"><![CDATA[
A może pokaż te funkcje CALLBACK, które Ci nie działają? Może będziemy w stanie Ci powiedzieć dlaczego <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1425">WoodPaker</a> — 30 kwi 2019, o 14:53</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[RychuER]]></name></author>
<updated>2019-03-15T13:17:24+01:00</updated>
<published>2019-03-15T13:17:24+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22075&amp;p=217366#p217366</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22075&amp;p=217366#p217366"/>
<title type="html"><![CDATA[Menu na LCD 2 x 16]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22075&amp;p=217366#p217366"><![CDATA[
Witam,<br /><br />chciałbym wykonać menu na LCD 2 x 16 z wykorzystaniem 4 klawiszy pozwalających na manipulację poziomami menu a mianowicie: UP, DOWN, MENU, EXIT. Do tej pory udało mi się jedynie zmieniać położenie w menu jednak z wykorzystaniem enkodera. Założenia są następujące:<br />- po starcie urządzenia na wyświetlaczu pojawia się informacja odnośnie temperatury odczytanej z czujnika oraz temperatury zadanej<br />- wciśnięcie klawisza MENU pozwala na przejście do listy menu a nawigacja odbywa się za pomocą klawiszy UP, DOWN<br />- ponowne wciśnięcie klawisza MENU na wybranej pozycji pozwala na zmiana wartości nastawy, którą regulujemy klawiszami UP, DOWN<br />- po wybraniu wartości klawiszem MENU zatwierdzamy wartość nastawy<br />- klawisz EXIT powoduje cofanie się w menu (np. przejście z submenu do menu głównego)<br /><br />Próbowałem już wielokrotnie przerobić na własne potrzeby pewien kod:<br />[syntax=c]void menu_idle(uint8_t event)<br />{<br />if (seconds &amp; 1) //z dwukropkiem<br />lcd_print_1st_line(&quot;== %02d:%02d ==&quot;, hours,minutes);<br />else //bez<br />lcd_print_1st_line(&quot;== %02d %02d ==&quot;, hours,minutes);<br />}<br /> <br />void menu_set_hours(uint8_t event)<br />{<br />switch (event)<br />{<br />case E_UP:<br />hours++;<br />//uwaga! czesc uC wolno liczy modulo!<br />hours %= 24;<br />break;<br /> <br />case E_DOWN:<br />hours--;<br />if (hours == 0xFF)<br />hours = 23;<br />}<br />lcd_printf_2nd_line(&quot; &gt;&gt; %02d &lt;&lt; %02d&quot;,hours, minutes);<br />}<br /> <br /> <br />void menu_set_minutes(uint8_t event)<br />{<br />switch (event)<br />{<br />case E_UP:<br />minutes++;<br />//uwaga! czesc uC wolno liczy modulo!<br />minutes %= 60;<br />break;<br /> <br />case E_DOWN:<br />minutes--;<br />if (minutes == 0xFF)<br />minutes = 59;<br />}<br />lcd_printf_2nd_line(&quot; %02d &gt;&gt; %02d &lt;&lt; &quot;,hours, minutes);<br />}<br /> <br />#define MENU_IDLE0 <br />#define MENU_SET_HR1 <br />#define MENU_SET_MIN2<br />#define MENU_PRINT_INFO3<br />#define MENU_SETTING_HR4<br />#define MENU_SETTING_MIN5<br /> <br />//niech callback == NULL oznacza, ze nie wywolujemy nic<br />//wybaczcie tabun liczb, inaczej tez by dobrze nie wygladalo...<br />const menu_item menu&#91;&#93; = {<br />// U, D, O, I<br />{{ 1, 1, 1, 0}, menu_idle, &quot;The current time is:&quot;},//idle menu (0)<br />{{ 3, 2, 4, 1}, NULL, &quot;Enter to set hours&quot;},//1st level set hour (1)<br />{{ 1, 3, 5, 2}, NULL, &quot;Enter to set minutes&quot;},//1st level set minutes (2)<br />{{ 2, 1, 3, 3}, NULL, &quot;Caladan 2010&quot;},//info menu (3)<br />{{ 4, 4, 1, 4}, menu_set_hours, &quot;Setting hours&quot;},//2nd level set hour (4)<br />{{ 5, 5, 2, 5}, manu_set_minutes, &quot;Setting minutes&quot;}//2nd level set minute (5)<br />};<br /> <br />void change_menu()<br />{<br />//przejdz do nastepnego <br />current_menu = menu&#91;current_menu&#93;.next_state&#91;menu_event&#93;;stanu<br />//wywolaj funkcje zwrotna<br />if (menu&#91;current_menu&#93;.callback)<br />menu&#91;current_menu&#93;.callback(menu_event);<br />//wyswietl komunikat <br />lcd_print_1st_line(menu&#91;current_menu&#93;.first_line);<br />//skasuj zdarzenie<br />menu_event = E_IDLE;<br />}[/syntax]<br /><br />Tutaj moja własna wersja na enkoderze (main.c):<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &lt;stdbool.h&gt;<br />#include &lt;stdint.h&gt;<br /><br />#include &quot;LCDHD44780/lcd44780.h&quot;<br />#include &quot;MENU/menu.h&quot;<br /><br />volatile int8_t encoder;<br /><br />int main(void)<br />{<br />lcd_init();<br />lcd_cls();<br /><br />startup();<br /><br />GICR |= (1&lt;&lt;INT0); //Uruchomienie przerwania INT0<br />MCUCR |= (1&lt;&lt;ISC00); //Reakcja na zbocze narastające i opadające<br /><br />sei(); //Zezwolenie na globalne przerwania<br /><br />while(1)<br />{<br />menu_pos();<br />}<br />}<br /><br />//Obsługa przerwania INT0<br />ISR(INT0_vect)<br />{<br />static uint8_t dir;<br /><br />if(!(PIND &amp; (1&lt;&lt;PD2)))<br />{<br />dir = (PIND &amp; (1&lt;&lt;PD3));<br />}<br />else<br />{<br />if(dir != (PIND &amp; (1&lt;&lt;PD3)))<br />{<br />if(dir) encoder++;<br />else encoder--;<br />}<br />}<br />}[/syntax]<br /><br />Plik menu.c:<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &lt;stdbool.h&gt;<br />#include &lt;stdint.h&gt;<br />#include &lt;stddef.h&gt;<br />#include &lt;string.h&gt;<br /><br />#include &quot;../LCDHD44780/lcd44780.h&quot;<br />#include &quot;menu.h&quot;<br /><br />extern volatile int8_t encoder;<br /><br />void startup(void)<br />{<br />DDRD |= LED_BLUE | LED_GREEN;<br /><br />PORTD |= ENKODER_A_LINE | ENKODER_B_LINE | ENKODER_BUTTON;<br /><br />LED_B_ON;<br />LED_G_ON;<br /><br />lcd_cls();<br />lcd_locate(0,0);<br />lcd_str(&quot;Zadana&quot;);<br />lcd_locate(0,13);<br />lcd_str(&quot;CO&quot;);<br />_delay_ms(4000);<br /><br />LED_B_OFF;<br />LED_G_OFF;<br />}<br /><br />void menu_pos(void)<br />{<br />switch (encoder)<br />{<br />case 1:<br />lcd_cls();<br />lcd_locate(0,0);<br />lcd_str(&quot;Tmp zadana CO&quot;);<br />_delay_ms(150);<br />break;<br /><br />case 2:<br />lcd_cls();<br />lcd_locate(0,0);<br />lcd_str(&quot;Moc nadmuchu&quot;);<br />_delay_ms(150);<br />break;<br /><br />case 3:<br />lcd_cls();<br />lcd_locate(0,0);<br />lcd_str(&quot;Pompa&quot;);<br />_delay_ms(150);<br />break;<br /><br />case 4:<br />lcd_cls();<br />lcd_locate(0,0);<br />lcd_str(&quot;Petla histerezy&quot;);<br />_delay_ms(150);<br />break;<br /><br />default:<br />lcd_cls();<br />lcd_locate(0,0);<br />lcd_str(&quot;Zadana&quot;);<br />lcd_locate(0,13);<br />lcd_str(&quot;CO&quot;);<br />_delay_ms(150);<br />break;<br />}<br /><br />if(encoder == 5) encoder = 1;<br />if(encoder &lt;= 0) encoder = 1;<br /><br />}[/syntax]<br /><br />Oraz plik menu.h:<br />[syntax=c]#ifndef MENU_MENU_H_<br />#define MENU_MENU_H_<br /><br />#define ENKODER_A_LINE (1&lt;&lt;PD2)<br />#define ENKODER_B_LINE (1&lt;&lt;PD3)<br />#define ENKODER_BUTTON (1&lt;&lt;PD5)<br /><br />#define ENKODER_BUTTON_DOWN (!(PIND &amp; ENKODER_BUTTON))<br /><br />#define LED_BLUE (1&lt;&lt;PD7)<br />#define LED_GREEN (1&lt;&lt;PD6)<br /><br />#define LED_B_ON PORTD |= LED_BLUE<br />#define LED_G_ON PORTD |= LED_GREEN<br /><br />#define LED_B_OFF PORTD &amp;= ~LED_BLUE<br />#define LED_G_OFF PORTD &amp;= ~LED_GREEN<br /><br />#define LED_B_TOGG PORTD ^= LED_BLUE<br />#define LED_G_TOGG PORTD ^= LED_GREEN<br /><br />void menu_pos(void);<br />void startup(void);<br /><br />#endif /* MENU_MENU_H_ */[/syntax]<br /><br />Największy problem sprawia mi napisanie poprawnej funkcji która obsłuży możliwość regulacji parametrów z submenu. Korzystałem już z poradników odnośnie CALLBACKÓW jednak funkcje nie reagują na działanie klawiszy czy też przycisku enkodera.<br /><br />Z góry dziękuje za pomoc i pozdrawiam <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=19338">RychuER</a> — 15 mar 2019, o 13:17</p><hr />
]]></content>
</entry>
</feed>