Permalänk
Medlem

Arduino + Knapp + Actuator

Hej

Jag vill först säga att jag är precis helt grön när det gäller programmering men jag försöker lära mig vart eftersom

Mitt projekt är att få till en automaticerad hundlucka. Tanken är att hunden kommer fram ställer sig på tryckkänslig platta som sedan öppnar acuatorn dörren, stannar till i 2 sek i öppet läge och sedan stänger.

Nybörjare som man är så börjar man med en funktion i taget.

Får kanppen att fungera med

const int buttonPin = 2; // Button const int ledPin = 13; // LED pin 13 // variables will change: int buttonState = 0; void setup() { // initialize the LED pin as an output: pinMode(ledPin, OUTPUT); // initialize the pushbutton pin as an input: pinMode(buttonPin, INPUT); } void loop() { // read the state of the pushbutton value: buttonState = digitalRead(buttonPin); // check if the pushbutton is pressed. If it is, the buttonState is HIGH: if (buttonState == HIGH) { // turn LED on: digitalWrite(ledPin, HIGH); } else { // turn LED off: digitalWrite(ledPin, LOW); } }

Knappen tänder upp LED på pin 13.

Får acuatorn att röra sig med hjälp av reläkortet

const int forwards = 7; const int backwards = 6; void setup() { pinMode(forwards, OUTPUT); pinMode(backwards, OUTPUT); } void loop() { digitalWrite(forwards, LOW); digitalWrite(backwards, HIGH);//Forwards delay(2000); // wait 2 seconds digitalWrite(forwards, HIGH); digitalWrite(backwards, HIGH);//Stopp delay(2000);// wait 2 seconds digitalWrite(forwards, HIGH); digitalWrite(backwards, LOW);//Backwards delay(2000);// wait 2 seconds digitalWrite(forwards, HIGH); digitalWrite(backwards, HIGH);//Stopp delay(2000);// wait 2 seconds }

Men när jag ska försöka få dessa att fungea ihopp så händer absolut ingenting. Har gjort åtskilliga försök men inte fått till det.

Behöver lite hjälp i rätt riktning.

Mvh
Chippen

Visa signatur

Dator = Ja

Permalänk
Medlem

@Chippen "Får acuatorn att röra sig med hjälp av reläkortet..."

Dum fråga kanske men du döper väl den andra funktionen till något annat än loop () så att du kan anropa den när du behöver?

Du kan läsa om funktioner här.

Permalänk
Medlem
Skrivet av windblownsnow:

@Chippen "Får acuatorn att röra sig med hjälp av reläkortet..."

Dum fråga kanske men du döper väl den andra funktionen till något annat än loop () så att du kan anropa den när du behöver?

Du kan läsa om funktioner här.

Nej, det hade jag inte koll på.

Jag har kikat på en annan kille som gjort en liknande lucka som använt sig av nedan, så jag har använt mig av loop.

void setup(){ //start serial connection Serial.begin(9600); pinMode(7, INPUT_PULLUP); // Pushbutton pinMode(13, OUTPUT); // doggydoor Open pinMode(12,OUTPUT); // Doggy Door shut } void loop(){ //read the pushbutton value into a variable int sensorVal = digitalRead(7); //print out the value of the pushbutton Serial.println(sensorVal); // Keep in mind the pullup means the pushbutton's // logic is inverted. It goes HIGH when it's open, // and LOW when it's pressed. Turn on pin 13 when the // button's pressed, and off when it's not: if (sensorVal == HIGH) { digitalWrite(13, LOW); } else { digitalWrite(13, HIGH); delay(10000); digitalWrite(12,HIGH); delay(10000); } }

Visa signatur

Dator = Ja

Permalänk
Medlem

Arduinons kernel kallar på två funktioner när den kör ett skript. Först kallar den på setup(); som förbereder arduinon med alla variablar, och sätter vilka pinnar som ska vara vad osv. efter det kör den igång loop(); som kör all kod i sig, och när den funktionen är klar så körs den bara igen.

Du kan sedan definera egna funktioner som du kan kalla på ifrån setup eller loop.

så det du behöver göra är att
if button == pressed
run motor

dvs flytta in koden för att köra motorn, i din ifsats som tänder lampan.

Visa signatur

CPU: Ryzen 9 3900x Noctua NH-D14 MOBO: TUF Gaming X570-PLUS GPU: GTX 980 RAM: 32 GB 3200 MHz Chassi: R4 PSU: Corsair AX860 Hörlurar: SteelSeries 840 Mus: Logitech G502 Lightspeed V.v. nämn eller citera mig för att få svar.

Permalänk
Medlem

Nu har jag fått det att lira

const int buttonPin = 2; // Button const int forward = 7; // Forward const int backward = 6; // Backword int buttonState = 0; void setup() { pinMode(forward, OUTPUT); pinMode(backward, OUTPUT); pinMode(buttonPin, INPUT); } void loop() { buttonState = digitalRead(buttonPin); // check if the pushbutton is pressed. If it is, the buttonState is HIGH: if (buttonState == HIGH) { // turn on: digitalWrite(forward, LOW); digitalWrite(backward, HIGH); delay(5000); digitalWrite(forward, HIGH); digitalWrite(backward, HIGH); delay(2000); digitalWrite(forward, HIGH); digitalWrite(backward, LOW); delay(5500); } else { // When OFF: digitalWrite(forward, HIGH); digitalWrite(backward, HIGH); } }

Men, jag skulle vilja att om knappen trycks till under sekvensen så ska den avbryta och börja om från början. Hur kan man lösa det enklast?

Visa signatur

Dator = Ja

Permalänk
Medlem
Skrivet av Chippen:

Men, jag skulle vilja att om knappen trycks till under sekvensen så ska den avbryta och börja om från början. Hur kan man lösa det enklast?

Problemet är att du använder delay(), som i stort sett pausar programmet den tid som du angett. delay() är ok för riktigt enkla program där man bara vill vänta ett tag och inget annat, men så fort man vill göra det lite mer komplicerat är det bästa att slopa delay och sköta tidtagningen själv med t.ex. millis(). Kolla in t.ex. denna sida för lite tips på hur man gör.

Sen kan det vara hjälpsamt att känna till att det är en tillståndsmaskin du försöker implementera. Om du tycker att det blir krångligt att få det att fungera korrekt så kan det vara hjälpsamt att rita upp tillstånden du har ("lucka stängd", "lucka öppnar", "lucka öppen", etc), och vilka övergångar du har mellan dem ("tid förfluten", "knapptryck", etc). Sen är det bara att ha en variabel som håller reda på vilket tillstånd du är i, och så gör du olika saker i loop() beroende på tillståndet.

Permalänk
Medlem
Skrivet av perost:

Problemet är att du använder delay(), som i stort sett pausar programmet den tid som du angett. delay() är ok för riktigt enkla program där man bara vill vänta ett tag och inget annat, men så fort man vill göra det lite mer komplicerat är det bästa att slopa delay och sköta tidtagningen själv med t.ex. millis(). Kolla in t.ex. denna sida för lite tips på hur man gör.

Sen kan det vara hjälpsamt att känna till att det är en tillståndsmaskin du försöker implementera. Om du tycker att det blir krångligt att få det att fungera korrekt så kan det vara hjälpsamt att rita upp tillstånden du har ("lucka stängd", "lucka öppnar", "lucka öppen", etc), och vilka övergångar du har mellan dem ("tid förfluten", "knapptryck", etc). Sen är det bara att ha en variabel som håller reda på vilket tillstånd du är i, och så gör du olika saker i loop() beroende på tillståndet.

Tack!

Otroligt bra sida! Detdär låter inte hel omöjligt att fåtill.

Skickades från m.sweclockers.com

Visa signatur

Dator = Ja

Permalänk
Medlem

Hej igen

Jag försöker få det att fungera med millis men kört fast.

class Flasher { int ledPin; long OnTime; long OffTime; int ledState; unsigned long previousMillis; public: Flasher(int pin, long on, long off) { ledPin = pin; pinMode(ledPin, OUTPUT); OnTime = on; OffTime = off; ledState = LOW; previousMillis = 0; } void Update() { unsigned long currentMillis = millis(); if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) { ledState = LOW; previousMillis = currentMillis; digitalWrite(ledPin, ledState); } else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) { ledState = HIGH; // turn it on previousMillis = currentMillis; digitalWrite(ledPin, ledState); } } }; Flasher led1(12, 100, 400); Flasher led2(13, 350, 350); Flasher led3(8, 500, 100); void setup() { } void loop() { if(digitalRead(2) == HIGH) { led1.Update(); led2.Update(); led3.Update(); } }

Så långt har jag kommit. Kör med led just nu bara för att det var enklare för tillfället men codningen bör vara den samma.
När jag trycker på knappen börjar det spelas upp och när jag släpper stannar det där det är och fortsätter vid nästa tryck.

Förmodligen behöver jag en "else" i loopen som sätter allt till av, men det får jag inte till.
Sen vill jag att när jag tryckt på knappen ska sekvensen spelas upp och sedan vänta tills nästa tryck och där har jag oxå kört fast.

Visa signatur

Dator = Ja

Permalänk
Medlem

Nu har det gått ett par månader och jag har gjort en hel del nya försök men inte riktigt nått i mål.

Just nu ser det ut såhär och det är långt ifrån fungerande. Men eftersom jag fortfarande är helt grön vad det gäller detta så vill jag ha feedback på om det öht är någon ideé att fortsätta på denna eller som det är skrota och börja om som gjäller.

enum State {IDLE, OPENING, PAUSING, CLOSING } state= IDLE; uint32_t start_time; const int buttonPin = 2; // Button const int forward = 7; // Forward const int backward = 6; // Backword int buttonState = 0; int forwardState = HIGH: int backwordState = HIGH: long forwardInterval = 3000; //On time forward long backwordInterval = 3000; //On time backword unsigned long currentMillis = 0; void setup() { pinMode(forward, OUTPUT); //Sets pin 7 to output pinMode(backword, OUTPUT); //Sets pin 6 to output pinMode(buttonPin, INPUT); //Sets buttonPin to input digitalWrite(forward, forwardState); digitalWrite(backward, backwardState); currentMillis = millis(); } void loop () { if(buttonPin = HIGH) { if(state == CLOSING) { turn off the closing actuator } state = OPENING; start_time = millis(); } else { switch(state) { case IDLE: // do nothing break; case OPENING: if(millis()-start_time >= opening time) { turn off the opening actuator; start_time = millis(); state = PAUSING; } // else do nothing break; case PAUSING: if(millis()-start_time >= pause time) { turn on the closing actuator; start_time = millis(); state = CLOSING; } // else do nothing break; case CLOSING: if(millis()-start_time >= close time) { turn off the closing actuator; state = IDLE; } // else do nothing break; } } }

Visa signatur

Dator = Ja

Permalänk
Entusiast

Jag tycker du ser ut att vara på god väg.

Det jag funderar över är det första som händer i loop() (förutom ett saknat = tecken). Du kollar om knappen är intryckt, och sätter dörren till att öppna. Men koden för att öppna körs inte för än knappen inte längre trycks in.
Som jag förstod det skulle det vara en tryckplatta man ställer sig på? Som det ser ut nu måste man gå av den för att något ska hända.

Jag hade nog separerat knappen från din switch case.

Du kan också kolla om knappen är intryckt innan du går från läget pausing till closing. Så att den stängs om man står kvar på knappen.