Sida 1 av 3
Arduino programmerings frågor.
Postat: 14 januari 2014, 16:06:02
av orvar-e
Vad gör jag för fel, håller på att testar lite och får inte till det. Vill bara att texten på displayen ska ändras när pin nr 10 blir hög. Men texten från när pin 10 är låg ligger kvar så det blir bara skit på displayen. Vart ska jag lägga "lcd.clear" så att displayen bara blir rensad en gång vid övergång från 0 till 1 och vise versa.
Försökt ett tag och koden ser ut så här nu.
Kod: Markera allt
/*
LiquidCrystal Library - display() and noDisplay()
Demonstrates the use a 16x2 LCD display. The LiquidCrystal
library works with all LCD displays that are compatible with the
Hitachi HD44780 driver. There are many of them out there, and you
can usually tell them by the 16-pin interface.
This sketch prints "Hello World!" to the LCD and uses the
display() and noDisplay() functions to turn on and off
the display.
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
Library originally added 18 Apr 2008
by David A. Mellis
library modified 5 Jul 2009
by Limor Fried (http://www.ladyada.net)
example added 9 Jul 2009
by Tom Igoe
modified 22 Nov 2010
by Tom Igoe
This example code is in the public domain.
http://arduino.cc/en/Tutorial/LiquidCrystalDisplay
*/
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int pinBlink = 10;
int buttonState = 0;
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
pinMode(pinBlink, INPUT);
// Print a message to the LCD.
}
void loop() {
buttonState = digitalRead(pinBlink);
// Turn off the display:
if (buttonState == HIGH) {
lcd.display();
delay(500);
// Turn on the display:
lcd.noDisplay();
delay(500);
lcd.setCursor(5,0);
lcd.print("Larm!");
lcd.setCursor(3,1);
lcd.print("High level!");
}
else {
}
if (buttonState == LOW)
{ lcd.setCursor(0,0);
lcd.print("Test1");
lcd.setCursor(4,1);
lcd.print("Inga larm");
lcd.setCursor(8,0);
lcd.print("Test2");
}
else{
}
}
Re: Arduino programmerings frågor.
Postat: 14 januari 2014, 16:16:19
av Klas-Kenny
Har inte kollat igenom koden, men för att svara på din fråga "Vart ska jag lägga "lcd.clear" så att displayen bara blir rensad en gång vid övergång från 0 till 1 och vise versa", så skulle du kunna göra så här:
Kod: Markera allt
/*
LiquidCrystal Library - display() and noDisplay()
Demonstrates the use a 16x2 LCD display. The LiquidCrystal
library works with all LCD displays that are compatible with the
Hitachi HD44780 driver. There are many of them out there, and you
can usually tell them by the 16-pin interface.
This sketch prints "Hello World!" to the LCD and uses the
display() and noDisplay() functions to turn on and off
the display.
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
Library originally added 18 Apr 2008
by David A. Mellis
library modified 5 Jul 2009
by Limor Fried (http://www.ladyada.net)
example added 9 Jul 2009
by Tom Igoe
modified 22 Nov 2010
by Tom Igoe
This example code is in the public domain.
http://arduino.cc/en/Tutorial/LiquidCrystalDisplay
*/
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int pinBlink = 10;
int buttonState = 0;
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
pinMode(pinBlink, INPUT);
// Print a message to the LCD.
}
void loop() {
buttonState = digitalRead(pinBlink);
// Turn off the display:
if (buttonState == HIGH) {
lcd.clear();
while(digitalRead(pinBlink)) {
lcd.display();
delay(500);
// Turn on the display:
lcd.noDisplay();
delay(500);
lcd.setCursor(5,0);
lcd.print("Larm!");
lcd.setCursor(3,1);
lcd.print("High level!");
}
lcd.clear();
}
else {
}
if (buttonState == LOW)
{ lcd.setCursor(0,0);
lcd.print("Test1");
lcd.setCursor(4,1);
lcd.print("Inga larm");
lcd.setCursor(8,0);
lcd.print("Test2");
}
else{
}
}
Re: Arduino programmerings frågor.
Postat: 14 januari 2014, 17:35:31
av sodjan
Jag vet inte om det bara är jag, men det här låter bakvänt:
Re: Arduino programmerings frågor.
Postat: 14 januari 2014, 17:45:10
av ToPNoTCH
Det är ju lite onödigt att ändra displayen varje loop, utan att tillståndet har ändrats på knappen (eller pinnen vad det nu var).
Förslag:
Lägg senaste status i en variabel och uppdatera BARA om aktuellt status skiljer sig från föregående status.
Nu kritar du ju om displayen hela tiden, varpå en rensning får det att se skit ut.
Re: Arduino programmerings frågor.
Postat: 14 januari 2014, 17:56:14
av orvar-e
När det blir larm så är det tänkt att displayen blinkar att det är larm och senare vad för larm.
Klas-Kenny .... har testat ditt förslag, när pin 10 går från 0 till 1 så börjar det blinka att det är larm utan att föregående text blir kvar, det är en förbättring.
När sedan larmet är kvitterat och pin 10 går från 1 till 0 så blir displayen blank inga tecken alls, sedan efter olika lång tid så hickar kortet till och texten dyker upp. Vad som händer där emellan har jag ingen aning om.
Ser att while villkoret gör att lcd rensas endast om pin 10 är 1, lyckas inte lägga in på viseveras än med framgång.
sodjan .... håller med det ser konstigt, har provat att kasta om det men resultatet blir inte bra. Jag är ny på det här så .......
Re: Arduino programmerings frågor.
Postat: 14 januari 2014, 17:56:36
av ToPNoTCH
Nått sådant här kanske...
(Otestad kod)
Kod: Markera allt
/*
LiquidCrystal Library - display() and noDisplay()
Demonstrates the use a 16x2 LCD display. The LiquidCrystal
library works with all LCD displays that are compatible with the
Hitachi HD44780 driver. There are many of them out there, and you
can usually tell them by the 16-pin interface.
This sketch prints "Hello World!" to the LCD and uses the
display() and noDisplay() functions to turn on and off
the display.
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
Library originally added 18 Apr 2008
by David A. Mellis
library modified 5 Jul 2009
by Limor Fried (http://www.ladyada.net)
example added 9 Jul 2009
by Tom Igoe
modified 22 Nov 2010
by Tom Igoe
This example code is in the public domain.
http://arduino.cc/en/Tutorial/LiquidCrystalDisplay
*/
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int pinBlink = 10;
int buttonState = 0;
int old_buttonState = 2;
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
pinMode(pinBlink, INPUT);
// Print a message to the LCD.
}
void loop() {
buttonState = digitalRead(pinBlink);
// Turn off the display:
if (buttonState == HIGH && old_buttonState == 0) {
old_buttonState = 1;
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Larm!");
lcd.setCursor(3,1);
lcd.print("High level!");
}
else {
if (buttonState == LOW && old_buttonState == 1 ) {
old_buttonState = 0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Test1");
lcd.setCursor(4,1);
lcd.print("Inga larm");
lcd.setCursor(8,0);
lcd.print("Test2");
}
}
}
Re: Arduino programmerings frågor.
Postat: 14 januari 2014, 18:01:34
av ToPNoTCH
Jaha...
Den skall blinka...Det var en annan sak...
Då får du fylla på mitt förslag med en till If sats i huvudloopen.
Om "old_buttonState == 0" toggla mellan "display()" och "noDisplay()"
Hellre toggla displayen på en räknare än på en Wait, för annars tappar du responsen på knappen då lösningen kommer ligga i en wait i praktiken hela tiden.
Re: Arduino programmerings frågor.
Postat: 14 januari 2014, 22:46:58
av ensten
orvar-e skrev:När det blir larm så är det tänkt att displayen blinkar att det är larm och senare vad för larm.
Klas-Kenny .... har testat ditt förslag, när pin 10 går från 0 till 1 så börjar det blinka att det är larm utan att föregående text blir kvar, det är en förbättring.
När sedan larmet är kvitterat och pin 10 går från 1 till 0 så blir displayen blank inga tecken alls, sedan efter olika lång tid så hickar kortet till och texten dyker upp. Vad som händer där emellan har jag ingen aning om.
Ser att while villkoret gör att lcd rensas endast om pin 10 är 1, lyckas inte lägga in på viseveras än med framgång.
sodjan .... håller med det ser konstigt, har provat att kasta om det men resultatet blir inte bra. Jag är ny på det här så .......
Ett förslag som jag har löst mina problem med är att rita (gärna på papper med penna) ett blockschema hur logiken för en viss funktion ska se ut. Man behöver inte (kanske till och med "ska inte") skriva som det skall kodas utan på ett sätt som gör det enkelt att se sambandet mellan olika skeenden i logiken. Jag har upptäckt ganska enkla (men fatala) feltänk i min kod när jag har gjort det. Dessutom har jag sett att jag kan effektivisera en hel del.
Mitt första försök med pannstyrningen blev 10K stort ganska snabbt, medan den versionen jag jobbar med nu har 4 ggr mer funktioner men ändå inte större än 12K. När man är nybörjare som vi är så är det jättebra att visualisera sina idéer med skisser.
Tyvärr inget tips direkt knutet till din fråga, men du får ju bra respons från andra här!
Fortsätt kämpa, det lossnar snart.

Re: Arduino programmerings frågor.
Postat: 15 januari 2014, 00:30:36
av Digitum
Personligen anser jag att delay() är en styggelse som aldrig någonsin skall användas i huvudprogrammet, eller ens i något av subprogrammen så vida det inte handlar om ett realtidsprogram och dessa brukar man väl inte skriva i C.
Jag skulle nog göra så här (Psudokod, gör resten själv):
Kod: Markera allt
int dMsg = 0; // Meddelande som skall visas, ändras av valfri funktion.
int cMsg = 0; // Meddelandet som just nu visas, ändras och läses endast av displayRefresh().
// 0 = blank skärm
// 1 och över är olika meddelanden
boolean btnStatus = false; // Anger knappens status vid senaste avläsningen, debouncat och klart. Läser inte ingången direkt då den kan vara störd.
void loop()
{
if(checkButton()) {
dMsg = (btnStatus?1:0); // Visa meddelande 1 om knappen är intryckt
}
displayRefresh(); // Uppdatera displayen
// Gör annat vettigt här i stället för att slösa bort den på delay();
}
void displayRefresh()
{
// Blinkfrekvens 1Hz, 50% dutycycle
if(millis()%1000<500) {
// Displayen skall vara tom under denna del av sekunden
if (cMsg > 0) { // Om den inte är det, blanka den nu
cMsg = 0;
display.clear();
}
} else {
// Displayen skall visa ett meddelande under denna del av sekunden, om sådant finns
if(cMsg != dMsg) {
// Om inte rätt meddelande visas så skall meddelandet ändras, annars är det bara att låta det vara
cMsg = dMsg;
if (cMsg > 0) { // Meddelande 0 är blankskärm
cMsg = 0;
display.clear();
}
if(cMsg = 1) {
display.show("Text 1");
}
if(cMsg = 2) {
display.show("Text 2");
}
... Osv. Allra bäst är det om du lägger textsträngarna i en array i stället och definierar dessa i början på programmet, Då kan du spara in några byte minne.
}
}
}
boolean checkButton()
{
// Funktionen returnerar true om förändring har skett.
// Tänk på att en debouncer kanske måste läggas till
if(pin = high && btnStatus == false) {
btnStatus = true;
return true;
}
if(pin = low && btnStatus == true) {
btnStatus = false;
return true;
}
return false;
}
Notera att vad som skall visas på skärmen är avskiljt från rutinen som faktiskt uppdaterar skärmen. På så sätt slipper du slösa bort tid i onödan. Programmet hinner ändå med ett par hundratusen loopar i sekunden eller så och man slipper dessutom timingproblem med tex serieporten etc.
Re: Arduino programmerings frågor.
Postat: 15 januari 2014, 15:33:09
av orvar-e
Digitum.... Nu kommer jag inte länge, det är sista if-satserna som jag inte får till. Jag har redigerat koden en del men sista biten vill sig inte.
Fel meddelandet lyder.
"blinkdips.ino: In function 'void displayRefresh()':
blinkdips:71: error: return-statement with a value, in function returning 'void'
blinkdips:76: error: return-statement with a value, in function returning 'void'
blinkdips:78: error: return-statement with a value, in function returning 'void'
blinkdips:80: error: expected `}' at end of input "
Kod: Markera allt
#include <LiquidCrystal.h>
int dMsg = 0; // Meddelande som skall visas, ändras av valfri funktion.
int cMsg = 0; // Meddelandet som just nu visas, ändras och läses endast av displayRefresh().
// 0 = blank skärm
// 1 och över är olika meddelanden
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int pinBlink = 10;
int buttonState = 0;
boolean btnStatus = false; // Anger knappens status vid senaste avläsningen, debouncat och klart. Läser inte ingången direkt då den kan vara störd.
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
pinMode(pinBlink, INPUT);
}
void loop() {
buttonState = digitalRead(pinBlink);
if(buttonState == HIGH) {
dMsg = (btnStatus?1:0); // Visa meddelande 1 om knappen är intryckt
}
displayRefresh(); // Uppdatera displayen
// Gör annat vettigt här i stället för att slösa bort den på delay();
}
void displayRefresh()
{
// Blinkfrekvens 1Hz, 50% dutycycle
if(millis()%1000<500) {
// Displayen skall vara tom under denna del av sekunden
if (cMsg > 0) { // Om den inte är det, blanka den nu
cMsg = 0;
lcd.clear();
}
} else {
// Displayen skall visa ett meddelande under denna del av sekunden, om sådant finns
if(cMsg != dMsg) {
// Om inte rätt meddelande visas så skall meddelandet ändras, annars är det bara att låta det vara
cMsg = dMsg;
if (cMsg > 0) { // Meddelande 0 är blankskärm
cMsg = 0;
lcd.clear();
}
if(cMsg = 1) {
lcd.print("Text 1");
}
if(cMsg = 2) {
lcd.print("Text 2");
}
//... Osv. Allra bäst är det om du lägger textsträngarna i en array i stället och definierar dessa i början på programmet, Då kan du spara in några byte minne.
}
}
// Funktionen returnerar true om förändring har skett.
// Tänk på att en debouncer kanske måste läggas till
if (btnStatus = HIGH&& btnStatus == false) {
btnStatus = true;
{
return true;
}
if (btnStatus = LOW && btnStatus == true) {
btnStatus = false;
{
return true;
}
return false;
}
}
ToPNoTCH ...... det funkar att byta text men inte att få larmtexten att blinka, som du säkert misstänkte.
Re: Arduino programmerings frågor.
Postat: 15 januari 2014, 15:37:25
av ensten
Du kan väl inte returnera ett värde ur en "Void"-rutin.
Du får skriva "boolean RutinensNamn()"
Re: Arduino programmerings frågor.
Postat: 15 januari 2014, 15:45:57
av orvar-e
se rad 15 ..... boolean btnStatus = false;
är det så du menar?
Re: Arduino programmerings frågor.
Postat: 15 januari 2014, 20:03:54
av eqlazer
Antar att ensten menar detta:
Kod: Markera allt
void displayRefresh()
{
/*...*/
return false;
}
Alltså inte returnera ett värde i en void-funktion. Om du däremot byter void till boolean så funkar det att returnera på det sätter du gör nu.
Re: Arduino programmerings frågor.
Postat: 15 januari 2014, 20:06:15
av ensten
Ja, exakt. en void rutin kan inte returnera (och om jag inte minns fel inte heller ta emot argument).
Re: Arduino programmerings frågor.
Postat: 15 januari 2014, 20:36:36
av Icecap
Kod: Markera allt
void MinRutin(void) {}
^ ^
| Tar inte emot någon variabel för att göra sitt jobb.
Svarar inte tillbaka med ett värde efter jobbet är avklarat