Lära sig programserings-tankegången? (Arduino)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
thewho
Inlägg: 1098
Blev medlem: 28 november 2008, 08:46:10
Ort: Finland, Åland

Lära sig programserings-tankegången? (Arduino)

Inlägg av thewho »

Hejsan

Jag försöker (för andra gången) lära mig programera Arduino, med begränsad framgång dock.. :doh:
Jag verkar ha väldigt svårt att förstå hur man ska tänka när man programerar, det verkar ibland ologiskt tycker jag.

Nu just kör jag fast när jag vill att en knapp ska börja dimma upp en led till max (0-255) och stanna där under en tid.
Jag funderar så här:
loopen ska vänta på ett knapptryck
om knappen blir tryckt ska loopen starta och sätta en variabel till t.ex KörLoop = TRUE?
när loopen har dimmat led'en till max och väntat där en tid så ändrar den samma variabel till FALSE och loopen väntar igen på att knappen ska ändra KörLoop till TRUE.

Tänker jag rätt här nu?

Om någon är intresserad så ska det bli (möjligtvis med lite tur) trappbelysning som dimmar upp stegen var för sig och som sen dimmar ner dom ett tag.
Användarvisningsbild
XCore
EF Sponsor
Inlägg: 963
Blev medlem: 31 januari 2009, 03:00:12

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av XCore »

Posta koden!
thewho
Inlägg: 1098
Blev medlem: 28 november 2008, 08:46:10
Ort: Finland, Åland

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av thewho »

Det här är allt jag har lyckats med för tillfället. Jag har inte gjort några försök att ändra 'running' till true för jag vet inte hur jag ändrar den när led'en är på max, utan att loopen ändrar den till true varje gång den körs.
Nu dimmar den upp bara när man håller ner knappen dock. Men det vet jag att är för att loopen bara kör om 'btnState' är HIGH.

Kod: Markera allt

int led = 3;
int btn = A0;
int brightness = 0;
int fadeAm = 5;
int btnState = 0;
boolean running = false;

void setup(){
  pinMode(led, OUTPUT);
  pinMode(btn, INPUT);
}

void loop (){
  btnState = digitalRead(btn);
  if (btnState == HIGH) {
    analogWrite(led, brightness);
    brightness = brightness + fadeAm;
    delay (30);
  }
}
Användarvisningsbild
Klas-Kenny
Inlägg: 11841
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av Klas-Kenny »

I just det här fallet finns ingen anledning till att sätta någon variabel på det viset. Gör istället en egen loop för att dimma upp lysdioden när knappen blivit intryckt, istället för att förlita dig på main-loopen.

Typ:

Kod: Markera allt

void loop (){
  btnState = digitalRead(btn);
  if (btnState == HIGH) {
    brightness = 0;
    while(brightness < 255){
      analogWrite(led, brightness);
      brightness = brightness + fadeAm;
      delay (30);
    }
  }
}
Men visst, vill du gå igenom main-loopen för det så kan du ju sätta en variabel som håller koll på att knappen tryckts in, sen en if-sats som kollar ifall du kommit upp i full ljusstyrka, och om den gjort det så sätter den variabeln till FALSE.
thewho
Inlägg: 1098
Blev medlem: 28 november 2008, 08:46:10
Ort: Finland, Åland

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av thewho »

Nu tror jag att jag förstår! :shock: Tackar :tumupp:
Jag återkommer säkerligen med fler frågor dock :lol:
Användarvisningsbild
Walle
Moderator
Inlägg: 7701
Blev medlem: 14 december 2004, 10:32:18
Ort: Stockholm

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av Walle »

Nu programmerar jag inte Arduino, men det kvittar i det stora hela.

Jag tänker att det är ett system som har fyra lägen, states:

State 1: väntar på knapptryckning.
State 2: dimmar upp.
State 3: Full styrka, väntar.
State 4: dimmar ned.
Tillbaka till state 1.

Det går att lösa allt i en loop, i flera loopar, eller med timers och interrupt (kanske inte finns i Arduino?)
Om du har en state-variabel så kan du låta den bestämma vad som ska göras med if-satser (eller ännu smidigare med en switch-sats).

I förenklad pseudokod blir det nåt liknande:

Kod: Markera allt

Switch(state)
{
Case 0: kolla efter knapptryckning. 
Case 1: dimmra upp
Case 2: vänta
Case 3: dimmra ned
}
Din switch-sats kan ligga i mainloop. Naturligtvis kan du använda hakparenteser inom switch-satsen.
thewho
Inlägg: 1098
Blev medlem: 28 november 2008, 08:46:10
Ort: Finland, Åland

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av thewho »

Nu fungerar det! :D

Men en följdfråga, vad gör 'brightness = 0;' ?

Kod: Markera allt

void loop (){
  btnState = digitalRead(btn);
  if (btnState == HIGH) {
    brightness = 0;                    <-- här
    while(brightness <255){
    analogWrite(led, brightness);
    brightness = brightness + fadeAm;
    delay (30);
    }
    delay (5000);
    digitalWrite(led, LOW);
  }
}
Användarvisningsbild
LHelge
Inlägg: 1772
Blev medlem: 2 september 2007, 18:25:31
Ort: Östergötland
Kontakt:

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av LHelge »

Då brightness är definierad globalt (dvs utanför loop-funktionen) så kommer den ihåg sitt värde nästa gång loop() körs. Om den inte sätts till 0 kommer den börja på det senaste värde som skrevs till den (255 i detta fall).
thewho
Inlägg: 1098
Blev medlem: 28 november 2008, 08:46:10
Ort: Finland, Åland

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av thewho »

Missade ditt inlägg Walle, inte för att jag förstår vad du menar dock :?

Ah! det borde jag ha kunnat klura ut själv :doh:

Men nu en ny fråga, varför går inte led'en till noll igen? Det fungerar som det ska om jag trycker på knappen igen, men stannar fortfarande före led'en är helt släckt.
Gissar att det är något fel efter rad 21 :humm:

Kod: Markera allt

int led = 3;
int btn = A0;
int brightness = 0;
int fadeAm = 5;
int btnState = 0;

void setup(){
  pinMode(led, OUTPUT);
  pinMode(btn, INPUT);
}

void loop (){
  btnState = digitalRead(btn);
  brightness = 0;
  if (btnState == HIGH) {
    brightness = 0;
    while(brightness <255){
    analogWrite(led, brightness);
    brightness = brightness + fadeAm;
    delay (30);
    }
    while(brightness >0){
    analogWrite(led, brightness);
    brightness = brightness - fadeAm;
    delay(30);
    }
  }
}
Användarvisningsbild
Klas-Kenny
Inlägg: 11841
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av Klas-Kenny »

Det beror på
while(brightness >0)

För när brightness har gått ner till 0 så skriver den aldrig det värdet till utgången. :)

Den enklaste lösningen för det är att kort och gott ändra till

Kod: Markera allt

while(brightness >0){
    brightness = brightness - fadeAm;
    analogWrite(led, brightness);
    delay(30);
    }
Sista gången den loopen går runt då, så ändras brightness till 0, skrivs till utgången, och sedan kontrolleras om brighness är större än noll, nej det är det inte, då är vi färdiga.

Som du har det nu går det istället till att brightness minskas till ett värde över 0, kontrolleras om det är över 0, det är det, skrivs till utgången, brightness minskas till 0, kontrolleras, nu är det inte större än noll, alltså skrivs det aldrig till utgången.

Notera skillnaden mellan > och >=, "större än" och "större än eller lika med".
thewho
Inlägg: 1098
Blev medlem: 28 november 2008, 08:46:10
Ort: Finland, Åland

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av thewho »

Ah, ännu en grej jag borde ha fattat.. :doh:
Tackar och bockar :tumupp:

Kan någon peka mig i rätt riktning om hur jag bygger på för att dimma upp led'arna efter varandra?

Hela koden för den som är intresserad:

Kod: Markera allt

int led = 3;
int btn = A0;
int brightness = 0;
int fadeAm = 5;
int btnState = 0;

void setup(){
  pinMode(led, OUTPUT);
  pinMode(btn, INPUT);
}

void loop (){
  btnState = digitalRead(btn);
  brightness = 0;
  if (btnState == HIGH) {
    brightness = 0;
    while(brightness <255){
    brightness = brightness + fadeAm;
    analogWrite(led, brightness);
    delay (30);
    }
    delay(5000);
    while(brightness >0){
    brightness = brightness - fadeAm;
    analogWrite(led, brightness);
    delay(30);
    }
  }
}
thewho
Inlägg: 1098
Blev medlem: 28 november 2008, 08:46:10
Ort: Finland, Åland

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av thewho »

Jag börjar förstå hur det här fungerar nu :D
Nu fungerar det som jag har tänkt, men man kan säkert göra koden på ett smartare sätt.
Så det är därför jag är här och frågar igen :wink:

Nu har jag bara kopierat dimfunktionen och ändrat led, led2, led3 osv.
Men man kan säkert krympa/ göra det smartare?

Kod: Markera allt

int led = 3;    //led pins 1-6
int led2 = 5;
int led3 = 6;
int led4 = 9;
int led5 = 10;
int led6 = 11;    
int btn = A0;    //button pin
int brightness = 0;    //brightness at time
int fadeAm = 5;    //fade per.
int btnState = 0;    //--!tillfällig knapp!--
int normlev = 0;    //min level
int highlev = 150;    //max level
int sens = A1;    //sensPin
int sensval = 0;    //sensorValue
int deltime = 30;    //delay updim
int deltime2 = 30;    //delay downdim

void setup(){
  pinMode(led, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(btn, INPUT);
  pinMode(sens, INPUT);
}

void loop (){
  sensval = analogRead(sens);                //read and set light sensor value
  sensval = constrain(sensval, 40, 700);     //constrain values
  sensval = map(sensval, 40, 700, 0, 255);   //----
  btnState = digitalRead(btn);               //read button state
  brightness = normlev;                      //sets brightness to normlev
  if (btnState == HIGH && sensval <= 10) {   //run only if dark and activated
    brightness = normlev;
    while(brightness < highlev){             //loop until brightness = highlev
    brightness = brightness + fadeAm;
    analogWrite(led, brightness);            //write pwm to led
    delay (deltime);                         //delay between loops
    }
    brightness = normlev;
    while(brightness < highlev){
    brightness = brightness + fadeAm;
    analogWrite(led2, brightness);
    delay (deltime);
    }
    brightness = normlev;
    while(brightness < highlev){
    brightness = brightness + fadeAm;
    analogWrite(led3, brightness);
    delay (deltime);
    }
    brightness = normlev;
    while(brightness < highlev){
    brightness = brightness + fadeAm;
    analogWrite(led4, brightness);
    delay (deltime);
    }
    brightness = normlev;
    while(brightness < highlev){
    brightness = brightness + fadeAm;
    analogWrite(led5, brightness);
    delay (deltime);
    }
    brightness = normlev;
    while(brightness < highlev){
    brightness = brightness + fadeAm;
    analogWrite(led6, brightness);
    delay (deltime);
    }
    
    delay(500); //-------------------------on time and dimdown
    
    brightness = highlev;
    while(brightness > normlev){
    brightness = brightness - fadeAm;
    analogWrite(led, brightness);
    delay(deltime2);
    }
    brightness = highlev;
    while(brightness > normlev){
    brightness = brightness - fadeAm;
    analogWrite(led2, brightness);
    delay(deltime2);
    }
    brightness = highlev;
    while(brightness > normlev){
    brightness = brightness - fadeAm;
    analogWrite(led3, brightness);
    delay(deltime2);
    }
    brightness = highlev;
    while(brightness > normlev){
    brightness = brightness - fadeAm;
    analogWrite(led4, brightness);
    delay(deltime2);
    }
    brightness = highlev;
    while(brightness > normlev){
    brightness = brightness - fadeAm;
    analogWrite(led5, brightness);
    delay(deltime2);
    }
    brightness = highlev;
    while(brightness > normlev){
    brightness = brightness - fadeAm;
    analogWrite(led6, brightness);
    delay(deltime2);
    }
   }
}
Zkronk
Inlägg: 1439
Blev medlem: 23 augusti 2005, 16:44:36
Ort: Uppsala

Re: Lära sig programserings-tankegången? (Arduino)

Inlägg av Zkronk »

Börja kika på for-loopen, den är väldigt bra att använda när man ska göra repetitiva uppgifter i programmet :)
Skriv svar