Arduino Polska Forum

Pełna wersja: Zliczanie do tyłu, kontrola za pomocą 2 przycisków.
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Witam,
Mam problem z kodem, który napisałem. Chcę wykonać układ, który na wyświetlaczu po wciśnięciu pierwszego przycisku zaczyna odliczanie od 10 do 0, natomiast drugi przycisk ma zatrzymać liczenie i wyświetlić napis. Ponowne wciśnięcie 1 przycisku ma na nowo zacząć odliczanie od 10 i tak w kółko. Wszystko jest w miarę ogarnięte. Problem jest w tym, że kiedy program zaczyna zliczać do 0, to nie mogę go tym drugim przyciskiem zatrzymać. Próbowałem już chyba wszystkiego, funkcje przerwań powodują, że program się zawiesza całkowicie, zastosowałem bibliotekę Timers aby programy działały równolegle. Skończyły mi się już pomysły, może któryś z Panów byłby w stanie mnie nakierować? Wklejam kod programu, przepraszam jeżeli jest mało czytelny bądź są w nim błędy, w programowanie Arduinno bawię się hobbystycznie i sporadycznie. Dzięki za wyrozumiałość. 
Kod:
#include <Wire.h>
#include "LiquidCrystal_I2C.h"
#include "Timers.h"
Timers <8> akcja;
int minuta = 10;
int sekunda = 0;
float mdziesiatki;
float mjednosci;
float sdziesiatki;
float sjednosci;
#define swiatlocz 4
#define swiatloni 5
#define klakson 6
#define przyciskcz 8
#define przyciskni 9
volatile int stala = 0;
volatile int stala2 = 0;
unsigned long licznik;
LiquidCrystal_I2C lcd(0x27,20, 4);

byte custchar[8][8] = {
{
  B11111,
  B11111,
  B11111,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
}, {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B11111,
  B11111,
  B11111
}, {
  B11111,
  B11111,
  B11111,
  B00000,
  B00000,
  B11111,
  B11111,
  B11111
}, {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B01110,
  B01110,
  B01110
}, {
  B00000,
  B00000,
  B00000,
  B01110,
  B01110,
  B01110,
  B00000,
  B00000
}, {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
}, {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
}, {
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
}
};

byte bignums[10][2][3] = {
{
  {255, 0, 255},
  {255, 1, 255}
},{
  {0, 255, 254},
  {1, 255, 1}
},{
  {2, 2, 255},
  {255, 1, 1}
},{
  {0, 2, 255},
  {1, 1, 255}
},{
  {255, 1, 255},
  {254, 254, 255}
},{
  {255, 2, 2},
  {1, 1, 255}
},{
  {255, 2, 2},
  {255, 1, 255}
},{
  {0, 0, 255},
  {254, 255, 254}
},{
  {255, 2, 255},
  {255, 1, 255}
},{
  {255, 2, 255},
  {254, 254, 255}
}
};

void loadchars() {
   for (int i = 0; i < 8; i++)
       lcd.createChar(i, custchar[i]);
   
/*    
   lcd.command(64);
   for (int i = 0; i < 8; i++)
       for (int j = 0; j < 8; j++)
           lcd.write(custchar[j]);
*/
   lcd.home();
}

void printbigchar(byte digit, byte col, byte row, byte symbol = 0) {
   if (digit > 9) return;
   for (int i = 0; i < 2; i++) {
       lcd.setCursor(col, row + i);
       for (int j = 0; j < 3; j++) {
           lcd.write(bignums[digit][i][j]);     //.kbv add the [i]
       }
       lcd.write(254);
   }
   if (symbol == 1) {
       lcd.setCursor(col + 3, row + 1);
       lcd.write(3);
   } else if (symbol == 2) {
       lcd.setCursor(col + 3, row);
       lcd.write(4);
       lcd.setCursor(col + 3, row + 1);
       lcd.write(4);
   }

   lcd.setCursor(col + 4, row);
}
void odczyt()
{
 
 if(digitalRead(8) == LOW)
  {
     stala = 1;
     licznik = millis();
   
  }
 else if(digitalRead(9) == LOW)
  {
     stala2 = 1;
     licznik = millis();
  }
  else if (digitalRead(10) == LOW)
  {
       stala = 0;
       stala2 = 0;
       licznik = 0;
   }
 else
   {
     return 0;
  }
}
void odliczanie()
{
for (minuta; minuta>0; sekunda--)
{
 
   lcd.setCursor(3,0);
   lcd.print("PRZEJECIE BAZY");
   lcd.setCursor(5,1);
   lcd.print("CZERWONYCH");

     if (sekunda == 0)
     {
       minuta = minuta - 1;
       sekunda = 59;

     }

     mjednosci = minuta%10;
     mdziesiatki = minuta/10%10;
     sjednosci = sekunda%10;
     sdziesiatki = sekunda/10%10;

   printbigchar(mdziesiatki, 3, 2);
   printbigchar(mjednosci, 7, 2, 2);
   printbigchar(sdziesiatki, 11, 2);
   printbigchar(sjednosci, 15, 2);
 


}
 
while (minuta == 0)
{

   lcd.clear();
   lcd.setCursor(3,0);
   lcd.print("BAZA CZERWONYCH");
   lcd.setCursor(6,1);
   lcd.print("PRZEJETA");
   printbigchar(0, 3, 2);
   printbigchar(0, 7, 2, 2);
   printbigchar(0, 11, 2);
   printbigchar(0, 15, 2);
 
   
}
}

void sterowanie()
{
   loadchars();
     if (stala == 1 && stala2 == 0)
     {
       stala2 = 0;
       digitalWrite(swiatloni, HIGH);
       odliczanie();

}
     
   else if (stala2 == 1 && stala == 0)
     {
       stala = 0;
   digitalWrite(swiatloni, LOW);
   lcd.clear();
   lcd.setCursor(3,0);
   lcd.print("BAZA CZERWONYCH");
   lcd.setCursor(5,1);
   lcd.print("BEZPIECZNA");
     }
   else if (stala2 == 0 && stala == 0)
     {

   digitalWrite(swiatloni, LOW);
   lcd.clear();
   lcd.setCursor(3,0);
   lcd.print("BAZA CZERWONYCH");
   lcd.setCursor(5,1);
   lcd.print("BEZPIECZNA");
     }
   else
   {
   lcd.clear();
   lcd.setCursor(3,0);
   lcd.print("AWARIA");
   }
}


void setup() {  
   lcd.begin();
   Serial.begin(9600);

   pinMode(8, INPUT_PULLUP);
   pinMode(9, INPUT_PULLUP);
   pinMode(2, INPUT_PULLUP);
   pinMode(4, OUTPUT);
   pinMode(5, OUTPUT);
   pinMode(6, OUTPUT);
   digitalWrite(swiatlocz, HIGH);
   digitalWrite(swiatloni, HIGH);
   akcja.attach(1, 400, odczyt);
   akcja.attach(2, 1500, sterowanie);
   
}

void loop() {
akcja.process();
   Serial.println(stala);
   Serial.println(stala2);
}
Napisz komentarze do tego kodu.
Co konkretnie robi każda z linii.
Do czego służą zmienne.
Narysuj schemat.

Naprawdę, nikt nie ma czasu na zgadywanie, jak działa ten program.
Po prostu faktycznie jesteś za cienki, napisz więcej prostych programów, więcej gotowych przeanalizuj, uporządkuj wiedzę kursami z gotowymi projektami: https://forbot.pl/blog/kursy.
By zrealizować projekt tego typu wystarczy rozmieć jak działają millis.
Przykład:
Kod:
const int buzzer=13;
const int button=2;
const int button2=3;
boolean stanbuzzera=0;

void setup() {
 // put your setup code here, to run once:
pinMode(buzzer,OUTPUT);
pinMode(button,INPUT_PULLUP);
pinMode(button2,INPUT_PULLUP);
//delay(10);
}

void loop() {
static int ilosc_pikow=20;
 // put your main code here, to run repeatedly:
 if(!digitalRead(2)||stanbuzzera)  dzwiek(100,ilosc_pikow,buzzer);
 if(!digitalRead(3)) stanbuzzera=0;
}

void dzwiek(uint16_t dlugosc, uint16_t pikniec, uint16_t pin) //(dlugosc piku, ile pikniec, na ktory pin)
{
static uint16_t aktualnyPik=0;
static boolean stanpoprzedni=0;
static uint32_t lasttime=0;
uint32_t currenttime=millis();

if((uint32_t)(currenttime-lasttime)>=(uint32_t)dlugosc)
{
 lasttime=currenttime;
 if( aktualnyPik++ <(pikniec*2))//mnozymy *2 by pikniec bylo 10, nie zmian stanu
 {
   digitalWrite(pin,!digitalRead(pin));
   stanbuzzera=1;
 }
 else
 {
  aktualnyPik=0;
  stanbuzzera=0;
 }

}
 
}

2 załączasz, 3 wyłączasz - pikanie, miganie ledami, czy odliczanie jakieś zmiennej.