• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
LCD menu
#1
Tongue 
Witam,
Jestem w trakcie robienia pewnego projektu, i potrzebuje wykonać menu z którym mam problem. Menu będzie wyświetlane na ekranie LCD 20x4 I2C i sterowane za pomocą enkodera wciskanego. Nie wiem jak sie zabrać za to, cały projekt już złożony, główny program gotowy ale brakuje menu. Na zdjęciu poniżej przedstawiona jest struktura menu jakie chciałbym uzyskać.

[Obrazek: attachment.php?aid=428]

Pierwsze okienko po lewej to wyświetlany tekst. Jak program wykryje naciśniecie enkodera, przechodzi do kolejnego okienka, jest to główne menu. Ostatnia opcja, opisana jako powrót powraca do wyświetlania tekstu z bloku pierwszego. 
W menu głównym po wybraniu pierwszej drugiej bądź trzeciej opcji, przechodzi do wyświetlania odpowiedniego podmenu. W każdym podmenu ostatnia opcja to powrót. Obok Tekstu w podmenu po prawej stronie ma wyświetlać wartość jakieś zmiennej którą możemy zmienić, za pomocą naciśnięcia enkodera i przekręcenia go w lewo badz w prawo, ponowne naciśnięcie enkodera powoduje zapisanie zmiennej jako ustawiliśmy i dalszą możliwość wybory

Np. Program wyświetla blok pierwszy czyli jakies dane z czujnikow. Układ ma sterować włączeniem wiatraka jak wykryje że temperatura odczytana jest wieksza o (wartość zmiennej x) od aktualnej temperatury, i aby zmienić o ile większa musi być temperatura by załączyć wiatrak musimy nacisnac enkoder, pokazuje nam się menu główne, następnie wchodzimy do ustawien(podmenu2), enkoderem lewo/prawo przechodzimy do miejsca gdzie jest napis temperatura a obok niej obecnie ustawiona wartosc(wartosc zmiennej x), naciskamy enkoder i zmieniamy wartość zmiennej x)

Proszę o jakąś pomoc z tym menu bo któryś dzień mnie to męczy.


Załączone pliki Miniatury
   
 
#2
Podaj kod jaki wyryłeś to postaramy ci pomóc .
Po drugie jak robisz zapętlenia na while czy wyświetlasz za pomocom switch.
[Obrazek: banerelektronika.jpg]



Jeśli pomogłem podziękuj punktem reputacji Wink
 
#3
Nie mam kodu do menu. Mam tylko serce programu czyli sterowanie przekaźnikami w odniesieniu do wprowadzonych wartości w zmiennych i porównywania tego z temperaturami z czujników temperatury. Na początku myślałem by zrobić wyświetlacz za pomocą switchu, dość sporo przełączania, najlepszym chyba rozwiązaniem będzie zrobienie tablicy i na tym bazować. Wcześniej nie robiłem aż tak rozbudowanych projektów i na tym etapie się zawiesiłem. To co chciałbym zrobić, niestety przewyższa moje umiejętnośći :/ Jeśli chodzi o enkoder, zmiany poprzez niego wprowadzone, to zrobiłem na przerwaniach. Na Arduino Nano, na którym bazuje ten projekt został wcześniej wykorzystany pin do przerwań, dlatego skorzystałem z biblioteki PinChangeInterrupt.h .
 
#4
To wzuć to co masz .
[Obrazek: banerelektronika.jpg]



Jeśli pomogłem podziękuj punktem reputacji Wink
 
#5
Obecnie mam to:

Kod:
//Biblioteki
#include <OneWire.h>                         //dodaj biblitekę LiquidCrystal.h
#include <DallasTemperature.h>               //dodaj biblitekę LiquidCrystal.h
#include <LiquidCrystal_I2C.h>
#include "PinChangeInterrupt.h"
//Przypisanie Pinów
#define dmuchawa 9
#define pompa 10
#define podajnik 11
#define disconnected 12 //Przekaźnik nie używany, zostawiony do przyszłej rozbudowy
#define switch1 2
#define rotaryA 4
#define rotaryB 3
//Zmienne
boolean sw1pre = 1, sw1akt = 1;
int x = 0, xpre = 0, one_wire = 8, value=0;                           //x, y - pozycja kursora, z zmienne pomocnicze menuTransmisja 1-Wire (czujniki temperatury na pinie 8)
float t1,t3,t5;                                //t1 - temperatura nastawiona, t3 - temperatura pieca, t5 - temperatura w pokoju
unsigned long czas = millis();                                          
unsigned long time = 0;
//Zainicjowanie Bibliotek
LiquidCrystal_I2C  lcd(0x27, 20, 4);
OneWire oneWire(one_wire);                   //wywołujemy transmisję 1-Wire na pinie 10
DallasTemperature sensors(&oneWire);         //informujemy Arduino, ze przy pomocy 1-Wire
//Utworzenie znaku kursora
byte cursor[8] = {
 0b11000,
 0b10100,
 0b10010,
 0b10001,
 0b10001,
 0b10010,
 0b10100,
 0b11000
};
void setup(void)
{
 lcd.createChar(0, cursor); //Utworzenie znaku kursora
 time = millis();
 pinMode(disconnected, OUTPUT);
 pinMode(dmuchawa, OUTPUT);
 pinMode(pompa, OUTPUT);
 pinMode(podajnik, OUTPUT);
 pinMode(switch1, INPUT_PULLUP);
 pinMode(rotaryA, INPUT_PULLUP);
 pinMode(rotaryB, INPUT_PULLUP);  
 digitalWrite(dmuchawa, HIGH);
 digitalWrite(pompa, HIGH);
 digitalWrite(podajnik, HIGH);
 digitalWrite(disconnected, HIGH);
 sensors.begin();                           //rozpocznij odczyt z czujnika
 lcd.begin();
 lcd.backlight();
 Serial.begin(9600);
 lcd.clear();                             //wyczysc ekran
 lcd.setCursor(1,0);
 lcd.print("STEROWNIK PIECA CO");
 lcd.setCursor(8,1);
 lcd.print("V1.0");
 lcd.setCursor(4,2);
   for(x=0; x<=12; x++){
     delay(800);
     lcd.print("#");
   }
   x=0;
   lcd.clear();
 attachPCINT(digitalPinToPCINT(switch1), pressbutton, FALLING);
 attachPCINT(digitalPinToPCINT(rotaryA), rotaryUP, RISING);
 attachPCINT(digitalPinToPCINT(rotaryB), rotaryDW, RISING);
}
//Obrót Enkodera w Lewo
void rotaryDW(void) {
 if ((millis() - time) > 50)
       value--;
       time = millis();
   }
//Obrót Enkodera w Prawo
void rotaryUP(void) {
 if ((millis() - time) > 50)
       value++;
       time = millis();
   }
//Nacisnięcie przycisku Enkodera
void pressbutton(){
 xpre = x;
 x++;
 value=0;
 }
//Wyświetlanie aktualnej temperatury
void menu(){
 if(xpre != x){
   lcd.clear();
   xpre = x;
 }
   
       lcd.setCursor(0,0);
       lcd.print("Temp. Nast.:");
       lcd.print(t1);
       lcd.setCursor(0,1);                       //ustaw kursor w pozycji 0,0
       lcd.print("Temp. Piec :");               //wyswietl "Temperatura: "
       lcd.print(t3);    //wyswietl wartosc z czujnika 0
       lcd.write(byte(223));                       //wyswietl znak stopnia
       lcd.print("C");      
       lcd.setCursor(0,2);                       //ustaw kursor w pozycji 0,0
       lcd.print("Temp. Pokoj:");               //wyswietl "Temperatura: "
       lcd.print(t5);    //wyswietl wartosc z czujnika 1
       lcd.write(byte(223));                       //wyswietl znak stopnia
       lcd.print("C");
 }
//Odczyt temperatury z czujników
void tempread(){
   sensors.requestTemperatures();            //zazadaj odczyt temperatury z czujnika
   t3 = sensors.getTempCByIndex(0);
   t5 = sensors.getTempCByIndex(1);
 }
void loop(void)
{
//Odczyt temeratury co 10s
   if((millis()- czas)> 10000){
     tempread();
     czas = millis();
   }
   menu();
}
Mam jeszcze algorytm jak ma się zachowywać program sterujący, który nie będzie wyzwaniem dlatego go jeszcze nie wpisałem w program. Odczyt temperatury na wyświetlaczy zrobiłem co 10s ponieważ bazując na bibliotece dallas skazuje program na opóźnienia, których chcę uniknąć ale uznałem, iż użycie tej biblioteki będzie najlepszym rozwiązaniem dla tej aplikacji. Proszę wybaczyć bałagan w kodzie, ma szczątki prób implementacji menu i testowaniu innych elementów.
 
#6
Kod:
//Biblioteki
#include <OneWire.h>                         //dodaj biblitekę LiquidCrystal.h
#include <DallasTemperature.h>               //dodaj biblitekę LiquidCrystal.h
#include <LiquidCrystal_I2C.h>
#include "PinChangeInterrupt.h"
//Przypisanie Pinów
#define dmuchawa 9
#define pompa 10
#define podajnik 11
#define disconnected 12 //Przekaźnik nie używany, zostawiony do przyszłej rozbudowy
#define switch1 2
#define rotaryA 4
#define rotaryB 3
//Zmienne
boolean sw1pre = 1, sw1akt = 1;
int x = 0, xpre = 0, one_wire = 8, value=0;                           //x, y - pozycja kursora, z zmienne pomocnicze menuTransmisja 1-Wire (czujniki temperatury na pinie 8)
float t1,t3,t5;                                //t1 - temperatura nastawiona, t3 - temperatura pieca, t5 - temperatura w pokoju
unsigned long czas = millis();                                          
unsigned long time = 0;
//Zainicjowanie Bibliotek
LiquidCrystal_I2C  lcd(0x27, 20, 4);
OneWire oneWire(one_wire);                   //wywołujemy transmisję 1-Wire na pinie 10
DallasTemperature sensors(&oneWire);         //informujemy Arduino, ze przy pomocy 1-Wire
//Utworzenie znaku kursora
byte cursor[8] = {
0b11000,
0b10100,
0b10010,
0b10001,
0b10001,
0b10010,
0b10100,
0b11000
};
void setup(void)
{
lcd.createChar(0, cursor); //Utworzenie znaku kursora
time = millis();
pinMode(disconnected, OUTPUT);
pinMode(dmuchawa, OUTPUT);
pinMode(pompa, OUTPUT);
pinMode(podajnik, OUTPUT);
pinMode(switch1, INPUT_PULLUP);
pinMode(rotaryA, INPUT_PULLUP);
pinMode(rotaryB, INPUT_PULLUP);  
digitalWrite(dmuchawa, HIGH);
digitalWrite(pompa, HIGH);
digitalWrite(podajnik, HIGH);
digitalWrite(disconnected, HIGH);
sensors.begin();                           //rozpocznij odczyt z czujnika
//lcd.begin();
lcd.backlight();
Serial.begin(9600);
lcd.clear();                             //wyczysc ekran
lcd.setCursor(1,0);
lcd.print("STEROWNIK PIECA CO");
lcd.setCursor(8,1);
lcd.print("V1.0");
lcd.setCursor(4,2);
   for(x=0; x<=12; x++){
     delay(800);
     lcd.print("#");
   }
   x=0;
   lcd.clear();
attachPCINT(digitalPinToPCINT(switch1), pressbutton, FALLING);
attachPCINT(digitalPinToPCINT(rotaryA), rotaryUP, RISING);
attachPCINT(digitalPinToPCINT(rotaryB), rotaryDW, RISING);
}
//Obrót Enkodera w Lewo
void rotaryDW(void) {
if ((millis() - time) > 50)
       value--;
       time = millis();
   }
//Obrót Enkodera w Prawo
void rotaryUP(void) {
if ((millis() - time) > 50)
       value++;
       time = millis();
   }
//Nacisnięcie przycisku Enkodera
void pressbutton(){
xpre = x;
x++;
value=0;
}
//Wyświetlanie aktualnej temperatury
void menu(){
if(xpre != x){
   lcd.clear();
   xpre = x;
}
  
       lcd.setCursor(0,0);
       lcd.print("Temp. Nast.:");
       lcd.print(t1);
       lcd.setCursor(0,1);                       //ustaw kursor w pozycji 0,0
       lcd.print("Temp. Piec :");               //wyswietl "Temperatura: "
       lcd.print(t3);    //wyswietl wartosc z czujnika 0
       lcd.write(byte(223));                       //wyswietl znak stopnia
       lcd.print("C");      
       lcd.setCursor(0,2);                       //ustaw kursor w pozycji 0,0
       lcd.print("Temp. Pokoj:");               //wyswietl "Temperatura: "
       lcd.print(t5);    //wyswietl wartosc z czujnika 1
       lcd.write(byte(223));                       //wyswietl znak stopnia
       lcd.print("C");
}
//Odczyt temperatury z czujników
void tempread(){
   sensors.requestTemperatures();            //zazadaj odczyt temperatury z czujnika
   t3 = sensors.getTempCByIndex(0);
   t5 = sensors.getTempCByIndex(1);
}
void loop(void)
{
//Odczyt temeratury co 10s
   if((millis()- czas)> 10000){
     tempread();
     czas = millis();
   }
   page();
   menu();
}


void page(int a){
switch(a){
  case 0:{
    if(digitalRead(switch1){
     a=1;
      
    }
    break;
  }
    case 1:{

      
   break;
  }
   case 2:{
    break;
  }
   case 3:{
    break;
  }
   case 4:{
    break;
  }
   case 5:{
    break;
  }

}
  
}
Tu masz zarys jak to ma wyglądając .
[Obrazek: banerelektronika.jpg]



Jeśli pomogłem podziękuj punktem reputacji Wink
 
#7
Użycie switcha byłoby zbyt proste i sam jeden switch nie podoła zadaniu. Jakby to miało tak wyglądać to dałbym sobie radę. Menu jakie chcę wykonać miałoby wyglądać tak jak mniej wiecej na tych filmikach

https://www.youtube.com/watch?v=CPPhRgpfsmY

albo

https://www.youtube.com/watch?v=xMkj4tGvFz8
 
#8
No to tak działo będzie to ty decydujesz sam jeden swich podoła nie mów ze nie bo dam ci kod na 2.4 tft gdzie tak mam zrobione.
Bo każdy case to jest to co wyświetlasz i pozycja szczałki.
[Obrazek: banerelektronika.jpg]



Jeśli pomogłem podziękuj punktem reputacji Wink
 
#9
To poproszę ten kod, chętnie go zobaczę. Może się czegoś za bardzo trzymam i przez to nie widzę aby to dało rade.
 
#10
https://drive.google.com/file/d/1m6k5dBT...sp=sharing
[Obrazek: banerelektronika.jpg]



Jeśli pomogłem podziękuj punktem reputacji Wink
 
  


Skocz do:


Przeglądający: 1 gości