Автор Тема: Затруднение с кода ( lcd 16x2 )  (Прочетена 8454 пъти)

moschino

  • Новодошъл
  • *****
  • Публикации: 6
    • Профил
Затруднение с кода ( lcd 16x2 )
« -: Април 29, 2013, 11:55:50 am »
Здравейте... създавам vending машина с четири слота. Целта ми е при натискане на един от четирите бутона да се активира бубината на реле, което от своя страна е ключ към захранващата верига на електромоторче с редуктор. До тук всичко е ок ... проблемът е в това, че искам всички действия да бъдат print-вани на lcd дисплей (16x2) т.е. ако няма натиснат бутон на дисплея да пише "Моля изберете артикул" , а след като някой от четирите бутона бъде натиснат и докато релето сработва да се изписва да речем "Вие избрахте Артикул 1" или артикул 2,3,4. Ето кодът с управлението на релетата:

#include <LiquidCrystal.h>

int relay1 = 22;
int relay2 = 23;
int relay3 = 24;
int relay4 = 25;
int button1= 30;
int button2= 31;
int button3= 32;
int button4= 33;
int button1status = 0;
int button2status = 0;
int button3status = 0;
int button4status = 0;
LiquidCrystal lcd(50, 51, 44, 45, 46, 47);

void setup() {
  lcd.begin(16, 2);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);
 
}

void loop(){
button1status = digitalRead(button1);
button2status = digitalRead(button2);
button3status = digitalRead(button3);
button4status = digitalRead(button4);

if(button1status == HIGH){
  digitalWrite(relay1,HIGH);
  delay(2000);
}else{
  digitalWrite(relay1,LOW);
}

if(button2status == HIGH){
  digitalWrite(relay2,HIGH);
  delay(2000);
}else{
  digitalWrite(relay2,LOW);
}

if(button3status == HIGH){
  digitalWrite(relay3,HIGH);
  delay(2000);
}else{
  digitalWrite(relay3,LOW);
}

if(button4status == HIGH){
  digitalWrite(relay4,HIGH);
  delay(2000);
}else{
  digitalWrite(relay4,LOW);
}


Пробвах в блоковете "if" да използвам


lcd.setCursor(0,0);
lcd.print(".........");


 , но уви - опресняването става или прекалено бързо или прекалено бавно и в крайна сметка пикселите на lcd-то само леко променят контраста си без да изобразяват нещо.

emil74

  • Зомбиран Роботостроител
  • *****
  • Публикации: 227
    • Профил
    • http://www.maystorio.com
Затруднение с кода ( lcd 16x2 )
« Отговор #1 -: Април 29, 2013, 04:22:17 pm »
Не видях код с включено обръщане към LCD в него, освен онова накрая. За него пък не знам къде е било сложено. Провери си свързването и контраста на LCD.
Нямам Ардуино покрай мен, но пробвай кода в този вид:

#include <LiquidCrystal.h>

int relay1 = 22;
int relay2 = 23;
int relay3 = 24;
int relay4 = 25;
int button1= 30;
int button2= 31;
int button3= 32;
int button4= 33;
int button1status = 0;
int button2status = 0;
int button3status = 0;
int button4status = 0;
LiquidCrystal lcd(50, 51, 44, 45, 46, 47);

void setup() {
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
lcd.begin (16, 2);

}

void loop(){
button1status = digitalRead(button1);
button2status = digitalRead(button2);
button3status = digitalRead(button3);
button4status = digitalRead(button4);

lcd.setCursor(1, 1);
lcd.print("Select item:");
lcd.noCursor();

if(button1status == HIGH){
digitalWrite(relay1,HIGH);
delay(2000);
}else{
digitalWrite(relay1,LOW);
}

if(button2status == HIGH){
digitalWrite(relay2,HIGH);
delay(2000);
}else{
digitalWrite(relay2,LOW);
}

if(button3status == HIGH){
digitalWrite(relay3,HIGH);
delay(2000);
}else{
digitalWrite(relay3,LOW);
}

if(button4status == HIGH){
digitalWrite(relay4,HIGH);
delay(2000);
}else{
digitalWrite(relay4,LOW);
}
}

booker

  • Новодошъл
  • *****
  • Публикации: 6
    • Профил
Затруднение с кода ( lcd 16x2 )
« Отговор #2 -: Април 29, 2013, 07:33:23 pm »
От това по-лесно няма на кьде........!!!!
Преди да започнеш с предлагането на артикули, седни да се образоваш......., поне малко!
Провери свьрзването на  lcd, използвай примерите от библиотеката, променяй ги и така ще свикнеш с командите и с използването им спрямо нуждите ти!
Относно вьпроса ти:

if(button1staus == HIGH)
{
lcd.clear();
digitalWrite(relay1, HIGH);
lcd.setCursor(0, 0);
lcd.print("You choose......");
delay(2000);
lcd.clear();
} else {
digitalWrite(relay1, LOW);
}

едит: Пиша от андроид с руска клавиатура и затова ми " бягат" някои букви!

emil74

  • Зомбиран Роботостроител
  • *****
  • Публикации: 227
    • Профил
    • http://www.maystorio.com
Затруднение с кода ( lcd 16x2 )
« Отговор #3 -: Април 29, 2013, 09:16:41 pm »
Най-добре е да махне всички if-ове, за да се види дали не е хардуерен проблемът. Възможно е просто да не е настроил контраста на дисплея.
Т.е. да даде само това:

#include <LiquidCrystal.h>

LiquidCrystal lcd(50, 51, 44, 45, 46, 47);

void setup() {
lcd.begin (16, 2);

}

void loop(){

lcd.setCursor(1, 1);
lcd.print("Select item:");
lcd.noCursor();
}


P.S:booker, няма защо да нападаш питащия. Вероятно е разработил останалата част, а сега иска малко да модифицира, т.е да "подправи" малко манджата, казано по готварски(не съм спец в кухнята).  :D

moschino

  • Новодошъл
  • *****
  • Публикации: 6
    • Профил
Затруднение с кода ( lcd 16x2 )
« Отговор #4 -: Април 29, 2013, 09:32:50 pm »
Благодаря за отговорите момчета,но booker айде преди да ми обясниш колко необразован съм :roll:   да прочетеш какво написах в началото , а именно:
 "Пробвах в блоковете "if" да използвам


lcd.setCursor(0,0);
lcd.print(".........");


, но уви - опресняването става или прекалено бързо или прекалено бавно и в крайна сметка пикселите на lcd-то само леко променят контраста си без да изобразяват нещо."

...та варианта който ти ми предлагаш вече го пробвах ... Нямам проблем с дисплея и контраста. Може би трябва да създам отделна функция за print-ване на lcd-то и да я извиквам в блока if или да създам counter който да отброява колко пъти се изпълнява командата lcd.print така че да я изпълни само един път. Някой друг да има идея ?

moschino

  • Новодошъл
  • *****
  • Публикации: 6
    • Профил
Затруднение с кода ( lcd 16x2 )
« Отговор #5 -: Април 29, 2013, 09:36:33 pm »
emil74 Хардуерът си ми работи и кодът който ти ми пусна си изкарва съобщението ... вие май и двамата ме взехте за пълен идиот ... проблемът идва когато print-вам в IF ....капиш ?

emil74

  • Зомбиран Роботостроител
  • *****
  • Публикации: 227
    • Профил
    • http://www.maystorio.com
Затруднение с кода ( lcd 16x2 )
« Отговор #6 -: Април 29, 2013, 09:56:59 pm »
Зад клавиатурата не мога да съдя кой колко знае. Обикновено питам. И нямам навик да си създавам мнение за някого, когото не познавам лично. Контрастът е един от "глупавите", но чести проблеми.
Не видях къде ми каза, че даденият от мен код работи, за да тестваме if-а. От първото ти обяснение останах с убеждението, че не ти изписва нищо. По принцип, когато пусна част от код, с намерение да търся грешка, очаквам обратна връзка какво става.

lcd.print() трябва да се изпълнява само веднъж при настъпване на промяна. Иначе ще премигва и ще се вижда бледо.
Аз лично, бих оставил чисто "Ардуинския" подход и бих работил с порт, вместо с имена на бутони. Бих го направил не с брояч, а с променлива, в която се записва старото състояние, да я наречем oldstate.
 Тя трябва да се променя при смяна на състоянието и изпълняването на условието да е свързано с това oldstate да се различава от контролираната променлива.
Ако държиш да работипш в стила на Ардуино, можеш да въведеш за всеки бутон отделна променлива oldstate: button1oldstate, button2oldstate...

Ето пример за тест, но трябва да се добави опция за повторно изписване на съобщение за избор на артикул;
#include <LiquidCrystal.h>

int relay1 = 22;
int relay2 = 23;
int relay3 = 24;
int relay4 = 25;
int button1= 30;
int button2= 31;
int button3= 32;
int button4= 33;
int button1status = 0;
int button2status = 0;
int button3status = 0;
int button4status = 0;
int button1oldstate, button2oldstate, button3oldstate, button4oldstate;
LiquidCrystal lcd(50, 51, 44, 45, 46, 47);

void setup() {
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
lcd.begin (16, 2);
lcd.setCursor(0, 0);
lcd.print("Select item:");
lcd.noCursor();
}

void statusMemorize(){
  button1oldstate=button1status;
  button2oldstate=button2status;
  button3oldstate=button3status;
  button4oldstate=button4status;
}

void loop(){
button1status = digitalRead(button1);
button2status = digitalRead(button2);
button3status = digitalRead(button3);
button4status = digitalRead(button4);

if(button1status != button1oldstate){
digitalWrite(relay1,button1status);
lcd.setCursor(0, 0);
lcd.print("Button 1 pressed");
lcd.noCursor();
delay(2000);
statusMemorize();  
}

if(button2status != button2oldstate){
digitalWrite(relay2,button2status);
lcd.setCursor(0, 0);
lcd.print("Button 2 pressed");
lcd.noCursor();
delay(2000);
statusMemorize();  
}

if(button3status != button3oldstate){
digitalWrite(relay3,button3status);
lcd.setCursor(0, 0);
lcd.print("Button 3 pressed");
lcd.noCursor();
delay(2000);
statusMemorize();  
}

if(button4status != button4oldstate){
digitalWrite(relay4,button4status);
lcd.setCursor(0, 0);
lcd.print("Button 4 pressed");
lcd.noCursor();
delay(2000);
statusMemorize();  
}

}


Включено повторно съобщение. Тествай, нямам в момента Ардуино за проверка!
#include <LiquidCrystal.h>

int relay1 = 22;
int relay2 = 23;
int relay3 = 24;
int relay4 = 25;
int button1= 30;
int button2= 31;
int button3= 32;
int button4= 33;
int button1status = 0;
int button2status = 0;
int button3status = 0;
int button4status = 0;
int button1oldstate, button2oldstate, button3oldstate, button4oldstate;
int groupstate, groupoldstate;
LiquidCrystal lcd(50, 51, 44, 45, 46, 47);

void setup() {
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
lcd.begin (16, 2);
lcd.setCursor(0, 0);
lcd.print("Select item:");
lcd.noCursor();
}

void statusMemorize(){
  button1oldstate=button1status;
  button2oldstate=button2status;
  button3oldstate=button3status;
  button4oldstate=button4status;
  groupoldstate=groupstate;
}

void loop(){
button1status = digitalRead(button1);
button2status = digitalRead(button2);
button3status = digitalRead(button3);
button4status = digitalRead(button4);

groupstate=button1status+button2status+button3status+button4status;

if (groupstate==0 && groupoldstate!=0){
lcd.setCursor(0, 0);
lcd.print("Select item:    ");
lcd.noCursor();
statusMemorize();
}

if(button1status != button1oldstate){
digitalWrite(relay1,button1status);
lcd.setCursor(0, 0);
lcd.print("Button 1 pressed");
lcd.noCursor();
delay(2000);
statusMemorize();  
}

if(button2status != button2oldstate){
digitalWrite(relay2,button2status);
lcd.setCursor(0, 0);
lcd.print("Button 2 pressed");
lcd.noCursor();
delay(2000);
statusMemorize();  
}

if(button3status != button3oldstate){
digitalWrite(relay3,button3status);
lcd.setCursor(0, 0);
lcd.print("Button 3 pressed");
lcd.noCursor();
delay(2000);
statusMemorize();  
}

if(button4status != button4oldstate){
digitalWrite(relay4,button4status);
lcd.setCursor(0, 0);
lcd.print("Button 4 pressed");
lcd.noCursor();
delay(2000);
statusMemorize();  
}

}

booker

  • Новодошъл
  • *****
  • Публикации: 6
    • Профил
Затруднение с кода ( lcd 16x2 )
« Отговор #7 -: Април 30, 2013, 12:02:41 am »
Не стига, че не можеш да направиш елементарна функция(lcd.print) и то с ардуино, ами се и сърдиш че те взимаме за незнаещ! Не искам нито да се заяждам нито да те обиждам, в по-горният ми пост ти дадох пример как да си направиш програмата и това 100% работи!!!!!!
Ето ти едно ВИДЕО от тази вечер да се убедиш в това което казвам!
Този код е същият който е и на клипчето с изключение на символите за кирилца, които са заместени с "Select item" и "You choose......."
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 9);

int relay1 = 8;
int button1= 10;
int button1status = 0;


void setup() {
  lcd.begin(20, 4);
  pinMode(relay1, OUTPUT);
  pinMode(button1, INPUT);
 }

void loop() {
 button1status = digitalRead(button1);

 lcd.setCursor(0, 0);
 lcd.print("Select item:");

if(button1status == HIGH)
 {
 lcd.clear();
 digitalWrite(relay1, HIGH);
 lcd.setCursor(0, 0);
 lcd.print("You choose......");
 delay(2000);
 lcd.clear();
 } else {
 digitalWrite(relay1, LOW);
 }
}

Ако сега пак кажеш че кода не работи, значи "повредата е в твоя телевизор"-капиш!

едит: emil74 не го нападам, просто го съветвам преди да почва с проектите да си набави нужните познания. В нета изобилства от готови програми за ардуино от които може да се научи много.....Той ако не може да се справи с една елементарна команда която я има и в примерите дори, какво да говорим за управление на графични дисплеи, GSM модеми и др. Казвам всичко това с най-добри чувстава! :D

moschino

  • Новодошъл
  • *****
  • Публикации: 6
    • Профил
Затруднение с кода ( lcd 16x2 )
« Отговор #8 -: Април 30, 2013, 12:08:34 am »
И така не става  :? ... релето се задейства, но на дисплея само бледо се оцветяват всички пиксели на клетките на първия ред ... Възможно ли е проблема да е в това че ползвам само 4-те от 8-те пина на дисплея за пренос на данни ?

moschino

  • Новодошъл
  • *****
  • Публикации: 6
    • Профил
Затруднение с кода ( lcd 16x2 )
« Отговор #9 -: Април 30, 2013, 12:20:55 am »
Мамка му ... открих проблема ... не е в кода а в захранването - понеже захранвам само от USB явно не достига достатъчно ток до дисплея когато през това време работи релето и електромоторчето към него. При захранване от 12V предполагам, че ще се реши проблема. Ще видя утре да си купя. Благодаря за помощта момчета

emil74

  • Зомбиран Роботостроител
  • *****
  • Публикации: 227
    • Профил
    • http://www.maystorio.com
Затруднение с кода ( lcd 16x2 )
« Отговор #10 -: Април 30, 2013, 10:57:06 am »
А се сърдиш, като казваме да си провериш хардуера(мога да си представя реакцията, ако бяхме споменали захранване) :)
  С код, при който прави refresh на всяка стъпка, със сигурност ще имаш проблем. Понеже попита, та да отговоря и на това: дисплеят може да се свързва с 4 линии за данни и работи без проблем, в това няма защо да се съмняваш.
  От USB токът би трябвало да е предостатъчен(освен ако не е някое малко лаптопче)! Аз захранвам основно през USB и то няколко периферни устройства, работещи заедно. За едно реле и един дисплей, няма начин да е проблем. Съпротивлението на подсветката предполагам, че е по спецификацията на дисплея...
  Да не би да се опитваш да захраниш през 7805? Предполагам знаеш, че 7805 сработва, когато входното напрежение е над 7-7,5V?
  Ако имаш 7805 и захранваш през USB, спокойно можеш да свържеш входа и изхода на 7805 на късо. Кондензаторите ще филтрират напрежението, което вече е стабилизирано достатъчно от захранването. И така ще работиш директно със захранване от USB порта.

moschino

  • Новодошъл
  • *****
  • Публикации: 6
    • Профил
Затруднение с кода ( lcd 16x2 )
« Отговор #11 -: Април 30, 2013, 11:34:44 am »
Това за 7805 е много полезна информация :) Благодаря ... Мен обаче доста ме домързя и си купих готов модул с 4 релета - чиста работа , иначе бих ползвал TIP 122 Дарлингтън  - 5V и 20-30 mA са напълно достатъчни за да се отпуши.
  Относно хардуера ... това не се брои  :D . Благодаря отново  :clap:

П.П. Чакам тези дни от Китай да дойде Coins Acceptor-а и да завърша кода...ако срещна затруднения ще пиша ... пък и да не срещна ще го публикувам за другите ентусиасти които се захванат с правенето на vending машина. Поздрави