• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Zliczanie obrotów z trzech czujników w ciągu 1 sek.
#1
Witam

Jestem w trakcie pisania programu na Arduino Uno który będzie nadzorował pracę trzech wentylatorów i dwóch czujników DHT 22 oraz wskazywał aktualny czas . Dokładnie będzie kontrolował czy żaden z wentylatorów się nie zablokował.
Obroty jednego wentylatora są liczone w ciągu 1 sek. Mając 3 wentylatory mam opóźnienie w przetwarzaniu kodu o 3 sek. Jak przerobić kod żeby w jednej pętli uzyskać obroty z wentylatorów w ciągu 1 sek ? 
Oczywiście nie chodzi mi o zmianę wartości "sampleTime" na 333  Tongue
Raczej żeby jedna pętle "millis" obejmowała wszystkie trzy.
Kod:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
const int wen_1 = 11; //wentylator nadmuch
const int wen_2 = 10; //wentylator wyciąg
const int wen_3 = 9; //wentylator okap
const unsigned long sampleTime = 1000;
void setup()
{
pinMode(wen_1, INPUT); //wentylator nadmuch
pinMode(wen_2, INPUT); //wentylator wyciąg
pinMode(wen_3, INPUT); //wentylator okap
  lcd.init(); // uruchomienie LCD
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("RPM1: ");

}
void loop()
{
//obroty wentylatora 1 nadmuch
int rpm1 = getRPM1();
displayRPM1(rpm1);
int rpm2 = getRPM2();
displayRPM2(rpm2);
int rpm3 = getRPM3();
displayRPM3(rpm3);
}
  float getRPM1()
{
  int count = 0;
  boolean flag = LOW;
  unsigned long currentTime = 0;
  unsigned long startTime = millis();
  while (currentTime <= sampleTime) 
{
  if (digitalRead(wen_1) == HIGH)
{
  flag = HIGH;
}
  if (digitalRead(wen_1) == LOW && flag == HIGH)
{
  count++;
  flag = LOW;
}
  currentTime = millis() - startTime;
}
  float count2rpm = int(60000. / float(sampleTime)) * count; //int 6000
  return count2rpm;
}
  void displayRPM1(int rpm1)
{
  lcd.setCursor(2, 2);
  lcd.print("    ");
  lcd.setCursor(2, 2);
  lcd.print(rpm1, DEC);
}
//obroty wentylatora 2 wyciąg
  float getRPM2()
{
  int count = 0;
  boolean flag = LOW;
  unsigned long currentTime = 0;
  unsigned long startTime = millis();
  while (currentTime <= sampleTime) 
{
  if (digitalRead(wen_2) == HIGH)
{
  flag = HIGH;
}
  if (digitalRead(wen_2) == LOW && flag == HIGH)
{
  count++;
  flag = LOW;
}
  currentTime = millis() - startTime;
}
  float count2rpm = int(60000. / float(sampleTime)) * count;
  return count2rpm;
}
  void displayRPM2(int rpm2)
{
  lcd.setCursor(9, 2);
  lcd.print("    "); 
  lcd.setCursor(9, 2);
  lcd.print(rpm2, DEC);

//obroty wentylatora 3 okap
}
  float getRPM3()
{
  int count = 0;
  boolean flag = LOW;
  unsigned long currentTime = 0;
  unsigned long startTime = millis();
  while (currentTime <= sampleTime) 
{
  if (digitalRead(wen_3) == HIGH)
{
  flag = HIGH;
}
  if (digitalRead(wen_3) == LOW && flag == HIGH)
{
  count++;
  flag = LOW;
}
  currentTime = millis() - startTime;
}
  float count2rpm = int(60000. / float(sampleTime)) * count;
  return count2rpm;
}
void displayRPM3(int rpm3)
{
  lcd.setCursor(16, 2);
  lcd.print("    ");
  lcd.setCursor(16, 2);
  lcd.print(rpm3, DEC);
}
  //koniec wentylatory
 
Odpowiedź
#2
Użyj przerwań np. na zbocze narastające, w przerwaniu dla każdego z wentylatorów dajesz zmienną i powiększasz ją o 1 z każdym wywołaniem przerwania, a w loop() sprawdzasz raz na 1s (z użyciem funkcji millis() do odnierzenia czasu) stan każdej ze zmiennych i od razu je resetujesz na 0.
 
Odpowiedź
#3
A jak chcesz żeby zrobił na przerwaniu zewnętrznym jak UNO ma tylko dwa a on potrzebuje 3??

Można to zrobić na przerwaniu PCINT ale to nie będzie takie proste
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#4
(07-11-2020, 11:32)Jarewa0606 napisał(a): A jak chcesz żeby zrobił na przerwaniu zewnętrznym  jak UNO ma tylko dwa a on potrzebuje 3??

Można to zrobić na przerwaniu PCINT ale to nie będzie takie proste
https://forum.arduinopolska.pl/watek-prz...pin%C3%B3w
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#5
Udało mi się zrobić taki kod.
Działa z założeniem. Czy można go jakoś jeszcze usprawnić żeby był zgodny ze sztuką ? Wink
Kod:
//07-11-2020
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
const int wen_1 = 11;
const int wen_2 = 10;
const int wen_3 = 9;
const int led = 7; //wyjście LED alarm
int led_stan;


void setup()    //-------------setup-------------

{//4
  pinMode(wen_1, INPUT);
  pinMode(wen_2, INPUT);
  pinMode(wen_3, INPUT);
  pinMode(led, OUTPUT); //led alarm
  lcd.init(); // uruchomienie LCD
  lcd.backlight();
  lcd.clear();
lcd.setCursor(0, 2);
lcd.print("N:");
lcd.setCursor(7, 2);
lcd.print("W:");
lcd.setCursor(14, 2);
lcd.print("O:");
}//4

void loop()     //------------loop----------------
{
digitalWrite(led, led_stan);

{//1            //-----------wentylatory----------

  boolean flaga = LOW;
  boolean flaga1 = LOW;
  boolean flaga2 = LOW;
   
  unsigned long interwal = millis();
  unsigned long impulsy_wen_1 = 0;
  unsigned long impulsy_wen_2 = 0;
  unsigned long impulsy_wen_3 = 0;
  led_stan = LOW;

  while(millis() - interwal <= 1000)   // Zliczanie w czasie jednej sekundy
  {//2
   
    if (digitalRead(wen_1) == HIGH)
    {flaga = HIGH;}
   
    if (digitalRead(wen_1) == LOW && flaga == HIGH)
   {impulsy_wen_1++;
   flaga = LOW;}

      if (digitalRead(wen_2) == HIGH)
    {flaga1 = HIGH;}
   
    if (digitalRead(wen_2) == LOW && flaga1 == HIGH)
   {impulsy_wen_2++;
   flaga1 = LOW;}
  
      if (digitalRead(wen_3) == HIGH)
    {flaga2 = HIGH;}
   
    if (digitalRead(wen_3) == LOW && flaga2 == HIGH)
   {impulsy_wen_3++;
   flaga2 = LOW;}
  
  }//2
  
   float obroty_1 = int(60.) * impulsy_wen_1;
   lcd.setCursor(2, 2);
   lcd.print("    "); 
   lcd.setCursor(2, 2);
   lcd.print(obroty_1,0);

   if (obroty_1 <= 100)
   {led_stan = HIGH;}
  
   float obroty_2 = int(60.) * impulsy_wen_2;
   lcd.setCursor(9, 2);
   lcd.print("    "); 
   lcd.setCursor(9, 2);
   lcd.print(obroty_2,0);

   if (obroty_2 <= 100)
   {led_stan = HIGH;}

   float obroty_3 = int(60.) * impulsy_wen_3;
   lcd.setCursor(16, 2);
   lcd.print("    ");
   lcd.setCursor(16, 2);
   lcd.print(obroty_3,0);

   if (obroty_3 <= 100)
   {led_stan = HIGH;}
 
}//1

}
              //--------koniec wentylatory-------
 
Odpowiedź
#6
Jeśli działa, nie naprawiaj.
 
Odpowiedź
#7
Nie rozumiem tego i po co to ?

float = int(duble)*uint

przecież wynik zawsze będzie liczba całkowitą wiec po co float??
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#8
(07-11-2020, 22:39)Jarewa0606 napisał(a): Nie rozumiem  tego  i po co to ?

float = int(duble)*uint

przecież wynik zawsze będzie liczba całkowitą  wiec po co float??

Dzięki za poradę, masz racje. poprawione.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości