Go Down

Topic: Hur ska jag avgöra vilken av två sensorer som triggas först? (Read 3790 times) previous topic - next topic

apocalyps

Hej!

Jag håller på med ett projekt där jag vill kunna avgöra vilken av två sensorer som triggas först. I nuläget har jag kopplat två enkla strömbrytare till en Arduino Uno som kontrollera varsin LED. När jag trycker på den ena strömbrytaren så tänds den ena LED:en och trycker jag på den andra strömbrytaren så släcks den första LED:en och tänder den andra. Jag vill att när en av strömbrytarna sluts så ska dess LED börja lysa och sedan ska den fortsätta att lysa enda till dess att jag nollställer... Dvs - då kan jag avgöra vilken av strömbrytarna som har blivit trycks på först.

Är det någon som vet vad jag behöver lägga till i min kod?

Mvh Martin

Code: [Select]
void setup() {                
 
 pinMode(13, OUTPUT);
 pinMode(12, OUTPUT);
 
 pinMode(2, INPUT);
 pinMode(4, INPUT);
}

void loop() {
 if (digitalRead(2) == LOW) {
   digitalWrite(13, HIGH);
   digitalWrite(12, LOW);  
 }
 if (digitalRead(4) == LOW) {
   digitalWrite(12, HIGH);
   digitalWrite(13, LOW);  
 }
}

Msquare

Du vil have en tilstands skift i stil med
A åben : B åben -> ingen LED
Og så ENTEN
A lukket : B åben -> LED A lyser
og fra det tidspunkt A lyser uanset hvad du gør med B
ELLER
A Åben : B lukket -> LED B lyser
og fra det tidspunkt lyser B uanset hvad du gør med A
--
Som du ser har jeg nu mere nøjagtigt beskrevet hvad der skal ske. Du kan endnu mere nøjagtigt beskrive det ... og når det er meget meget nøjagtigt og detaljret, så er programmet skrevet. Så skal et bare skrives i C-syntax.
Tricket du har her, at du nok skal have en variabel der siger LED-A-lys-tilstand (true/false) og når den er true så checker du kun på om "nollställ" - du skal ikke kigge på knapperne mere.
"Nolställer" - du har ikke sagt hvad det er: Begge åben igen, eller RESET, eller en 3. knap?

apocalyps

Hej Msquare,

Tack, din beskrivning stämmer precis. När jag menar "nollställ" så menar jag RESET. Jag är en nybörjare på programmering så jag vet inte riktigt hur en sådan programkod ser ut, men jag ska kolla om jag kan få till något som fungerar. Om du/någon har något förslag så får ni gärna tipsa hur jag kan förändra min kod.

Jag postar en bild över hur jag har kopplat också (på bilden syns bara en strömbrytare och en LED, men den andra är inkopplad exakt likadant.

//Martin

Msquare

Tips #2 (siden den første ikke var tydlig nok :) )
Code: [Select]

boolean IngenLED = true ;
  :
if ( IngenLED )  // har endnu ikke valgt LED
  {
  kod der tester. Hvis en er trykt, tænd den LED og
    IngenLED = false ;
  }


apocalyps

Tack för hjälpen,

Tyvärr är jag fortfarande helt förvirrad - jag har försökt på alla möjliga vi men jag får inte till det :-(
Men jag får nog läsa på lite om hur man ska programmera...vilket enkelt kan ses på följande kod

Code: [Select]
//int IngenLED = 12;
//int LED = 13;

void setup() {               
 
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
 
  pinMode(2, INPUT);
  pinMode(4, INPUT);

}

void loop() {

  static boolean IngenLED = true;
   
//static boolean LED = false;
  //if (IngenLED) {
   //digitalRead(2) == LOW;
   // digitalWrite(13, HIGH);
   //IngenLED = false;
  if (IngenLED) {
    digitalRead(4) == LOW;
     digitalWrite(12, HIGH);
  IngenLED = false;
  //if (digitalRead(2) == LOW && IngenLED == true) {
//digitalWrite(13, HIGH);
  //if (digitalRead(4) == LOW && IngenLED == false) {
//digitalWrite(12, HIGH); // 13 green LED, 12 red LED   
//if ( IngenLED )  // har endnu ikke valgt LED
// {
  //kod der tester. Hvis en er trykt, tænd den LED og
    //IngenLED = false;
  }
  }

//}
   // } 

Msquare

Jeg synes(tycker) det er for svært at forklare programmering via forum. En hjælpende hånd, henvisning til en algoritme, osv det er OK. Jeg fornemmer en stigende panik ...

Den der "IngenLED" er som en lås. Hvis IngenLED er True, dvs vi har endnu ikke rykt/koblet en kontakt, så tester vi som før, i dit første program. Hvis den er false, dvs vi HAR valgt en LED så hopper vi over test af kontakter og derved ignorerer hvad der sker med dem.

Til dit første program så tilføjer du testen "if (IngenLED ) {  alt det der med at test kontakt og tænda LED }
Bemærk dom ekstra {} som alt bliver udført eller intet bliver udført afhængig af IngenLED.

I din kode hvor du tænder en LED skal du også bruge "IngenLED = false ;" - nu har du jo en tændt en LED.

Så skulle det virke....

En helt anden teknik er at lige efter du har tændt din LED så bruger du "while(1) ;" - det er det samme som at programmet stopper der og ALDRIG kommer videre (indtil RESET knappen tryks).

apocalyps

Hej igen! Tack för att du tar dig tid att förklara. Jag har faktiskt fått till det så att det fungerar. Se följande kod. Tack igen.

/Martin

Code: [Select]
void setup() {               
 
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
 
  pinMode(2, INPUT);
  pinMode(4, INPUT);
}

void loop() {
  if (digitalRead(2) == LOW) {
    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
    //delay(1000); // ditlagt av mig
while( digitalRead(2) == HIGH) { }
  }
  if (digitalRead(4) == LOW) {
    digitalWrite(12, HIGH);
    digitalWrite(13, LOW);
    //delay(1000); // ditlagt av mig
while( digitalRead(4) == HIGH) { } 
  }
}

dansan

Hej!

Jag gjorde om koden i dit problem lite. Var det meningen att knapp2 skulle göra Reset?
I vilket fall så blev det så här:
KnappA tänder Led1 i läget då KnappA trycks in. Det finns ett värde hur länge knappen "får" vara intryckt innan den känner av att man trycker på knappen igen, variabeln debounce. Detta för att få bort lite störningar när inputen går från Low till High.
Trycker man gång nr 2 så släcks Led1 och tänder Led2.
Om KnappB trycks in så gör man reset och slänger både Led1 och Led2.

På Uno-kortet så kan man använd Interrupt på pin 2 (pin 2 = interrupt 0) och 3 (pin 3 = interrupt 1) . Dvs gör något när knappen trycks in eller ändrar från High till Low osv. RISING är att ingången ändrar från Low till High. Här finns info om attachInterrupt och hur det fungerar http://arduino.cc/en/Reference/AttachInterrupt
Genom att använda interrupt på knapparn så blir renare kod i loop-metoden för annan logik som körs helatiden.


Code: [Select]

int buttonAPin = 2;    // button A pin number (interrupt 0)
int buttonBPin = 3;    // button B pin number (interrupt 1)

int ledAPin = 12;      // led A pin number
int ledBPin = 13;      // led A pin number

volatile long time = 0; // the last time the output pin was toggled
long debounce = 400; // the debounce time, increase if the output flickers

volatile byte lastCount = 0; // 0 to 255

void setup() {
  pinMode(ledAPin, OUTPUT);
  pinMode(ledBPin, OUTPUT);
 
  // Arduino Uno interrupt setting:
  attachInterrupt(0, onButtonAPress, RISING);
  attachInterrupt(1, reset, RISING);
}

void loop() {
  // Do something else here.
}

void toggleLed() {
  switch (lastCount % 2 == 0) {
    case 0:
digitalWrite(ledAPin, HIGH);
digitalWrite(ledBPin, LOW);
      break;
    case 1:
digitalWrite(ledAPin, LOW);
digitalWrite(ledBPin, HIGH);
      break;
    default:
      digitalWrite(ledAPin, LOW);
digitalWrite(ledBPin, LOW);
  }
}

void onButtonAPress() {
  if (millis() - time > debounce) {
if (lastCount == 255)
lastCount = 0;
else
lastCount++;
time = millis();
}
toggleLed();
}

void reset() {
if (millis() - time > debounce) {
lastCount = 0;
digitalWrite(ledAPin, LOW);
digitalWrite(ledBPin, LOW);
time = millis();
}
}



Mvh
Dan

Msquare

Også en løsning - hvis den virker.  :)

Jeg svarer blot fordi min personlige holdning/anbefaling (baseret på en del erfaring) er at man bør undgå bruge interrupts før man er nødt til at bruge dem (f.eks læse en encoder signal som kommer lidt for hyppigt at man kan polle den). De har mange subtile fejlkilder, og kan gøre debugging yderst vanskelig. Læse tilstanden af knapper der betjenes af finger er ikke en interrupt krævende applikation.

Go Up