Arduino programmerings frågor.

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
orvar-e
EF Sponsor
Inlägg: 5973
Blev medlem: 9 mars 2007, 09:01:32
Ort: Borlänge

Arduino programmerings frågor.

Inlägg 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{
  }
}
Användarvisningsbild
Klas-Kenny
Inlägg: 11769
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Arduino programmerings frågor.

Inlägg 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{
  }
}
sodjan
EF Sponsor
Inlägg: 43231
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Arduino programmerings frågor.

Inlägg av sodjan »

Jag vet inte om det bara är jag, men det här låter bakvänt:

Kod: Markera allt

  // Turn on the display:
  lcd.noDisplay();
ToPNoTCH
Inlägg: 5097
Blev medlem: 21 december 2009, 17:59:48

Re: Arduino programmerings frågor.

Inlägg 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.
Användarvisningsbild
orvar-e
EF Sponsor
Inlägg: 5973
Blev medlem: 9 mars 2007, 09:01:32
Ort: Borlänge

Re: Arduino programmerings frågor.

Inlägg 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å .......
ToPNoTCH
Inlägg: 5097
Blev medlem: 21 december 2009, 17:59:48

Re: Arduino programmerings frågor.

Inlägg 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");
  }
}
}
ToPNoTCH
Inlägg: 5097
Blev medlem: 21 december 2009, 17:59:48

Re: Arduino programmerings frågor.

Inlägg 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.
Användarvisningsbild
ensten
EF Sponsor
Inlägg: 3759
Blev medlem: 19 oktober 2004, 15:55:20
Ort: Hudiksvall

Re: Arduino programmerings frågor.

Inlägg 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. :bravo:
Användarvisningsbild
Digitum
Inlägg: 153
Blev medlem: 9 februari 2006, 17:19:59

Re: Arduino programmerings frågor.

Inlägg 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.
Användarvisningsbild
orvar-e
EF Sponsor
Inlägg: 5973
Blev medlem: 9 mars 2007, 09:01:32
Ort: Borlänge

Re: Arduino programmerings frågor.

Inlägg 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.
Användarvisningsbild
ensten
EF Sponsor
Inlägg: 3759
Blev medlem: 19 oktober 2004, 15:55:20
Ort: Hudiksvall

Re: Arduino programmerings frågor.

Inlägg av ensten »

Du kan väl inte returnera ett värde ur en "Void"-rutin.

Du får skriva "boolean RutinensNamn()"
Användarvisningsbild
orvar-e
EF Sponsor
Inlägg: 5973
Blev medlem: 9 mars 2007, 09:01:32
Ort: Borlänge

Re: Arduino programmerings frågor.

Inlägg av orvar-e »

se rad 15 ..... boolean btnStatus = false;
är det så du menar?
eqlazer
Inlägg: 923
Blev medlem: 22 september 2007, 13:53:45
Ort: Göteborg

Re: Arduino programmerings frågor.

Inlägg 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.
Användarvisningsbild
ensten
EF Sponsor
Inlägg: 3759
Blev medlem: 19 oktober 2004, 15:55:20
Ort: Hudiksvall

Re: Arduino programmerings frågor.

Inlägg av ensten »

Ja, exakt. en void rutin kan inte returnera (och om jag inte minns fel inte heller ta emot argument).
Användarvisningsbild
Icecap
Inlägg: 26612
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Arduino programmerings frågor.

Inlägg 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
Skriv svar