Arduino Polska Forum

Pełna wersja: Encoder na przerwaniach - czy tak może być?
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Cześć,

Przerwania to dla mnie jeszcze pewne wyzwanie Wink

Mam enkoder (wybierak) i chcę odczytać jego ruch.

Przeszukałem internet i znalazłem kilka rozwiązań
Na początku chciałem klasycznie wykrywać "wzrost" na pinie i odczyt drugiego pinu - i na zasadzie czy ten drugi jest wysoki czy niski ustalam kierunek obrotu, ale okazało się że dane są pomieszane (pewnie drgania styków) 
Kombinowałem z ograniczeniem częstotliwości ale to i tak czasem powodowało błędny odczyt.


Ostatecznie mam taką funkcje która każdy obrót odczytuje poprawnie Smile ale i tak chciałbym podpytać jak można przyspieszyć funkcję (mam dużo ifów podejrzewam że to daje spore opóźnienie...)
NA początku szukania trafiłem na informacje że funkcje z przerwań można wymusić żeby były w ramie (szybciej się powinny wykonywać) ale teraz nie pamiętam jak to wymusić Sad

Kod:
byte InputKola1A = 33;
byte InputKola1B = 36;



volatile int count1 = 0;
volatile byte stan_kola=0;

int last_count1 = 9999;





void setup() {
  Serial.begin(115200);
  pinMode(InputKola1A, INPUT);
  pinMode(InputKola1B, INPUT);
  Serial.println("start");

  //CHANGE, LOW,RISING,FALLING
 
// attachInterrupt(digitalPinToInterrupt(interruptPin), blink, );

attachInterrupt(InputKola1A, Kolo1A, CHANGE); 
attachInterrupt(InputKola1B, Kolo1B, CHANGE);

}


void Kolo1A() {//funkcja odpowiadająca za reakcję na zmianę stanu na PINie A

  if (digitalRead(InputKola1A)){
  if(stan_kola==0)//pierwszy "wzrost"
    {
      stan_kola=B10000000;
    }
  if(stan_kola==B01000000)//drugi "wzrost" 
  {
    stan_kola=B01100000;
   
  }
  }
  else
  {
    if((stan_kola==B10010000)||(stan_kola==B01100000))//pierwszy "spadek"
    {
      stan_kola=stan_kola | B00001000;
    }
  if((stan_kola==B10010100)||(stan_kola==B01100100))//drugi "spadek" 
  {
    stan_kola=stan_kola | B00000010;
  
    if(stan_kola==B01100110){count1--;}
    stan_kola=0;
    

  }
  }


}


 
void Kolo1B() {//funkcja odpowiadająca za reakcję na zmianę stanu na PINie B

  if (digitalRead(InputKola1B)){
  if(stan_kola==0)//pierwszy "wzrost"
    {
      stan_kola=B01000000;
    }
  if(stan_kola==B10000000)//drugi "wzrost" 
  {
    stan_kola=B10010000;
  }
  }
  else
  {
  if((stan_kola==B10010000)||(stan_kola==B01100000))//pierwszy "spadek"
    {
      stan_kola=stan_kola | B00000100;
     
    }
  if((stan_kola==B10011000)||(stan_kola==B01101000))//drugi "spadek" 
  {
    stan_kola=stan_kola | B00000001;
   
     if(stan_kola==B10011001){count1++;}
    stan_kola=0;
  }
  }


}



void loop() {

  if(last_count1!=count1){
       Serial.println(count1);
       last_count1=count1;
  }
  

}


W "stan_kola" zapisuje bitowo kolejność stanów na koniec sprawdzam czy "przebieg" jest zgodny z oczekiwanym i na tej zasadzie zmieniam licznik count1.
Zainstaluj bibliotekę https://github.com/brianlow/Rotary/archive/master.zip
Ja wykorzystuję ją do odczytu kierunku.
Jeśli pracujemy na uC Atmela to:
Podpinamy enkoder pod piny z wyzwalaniem zewnętrznego przerwania (dla Uno itp, będą to 2,3).
Tworzymy obiekt enkodera:

Cytat:Rotary enkoder = Rotary(2,3);


Wtedy można napisać funkcję obsługi przerwania (ja tak robię)

Kod:
ISR(PCINT2_vect) {
  unsigned char result = enkoder.process();
  if (result) {   
    if (result == DIR_CW){//obsługa enkodera w prawo}
    else {//obsługa enkodera wlewo};      
  }
}
Mam problem z enkoderem tzn nie umiem odpalić go w przerwaniach a jedynie cyklicznie w pętli. Płytka na której to chodzi to mega_256 i to też tak jakoś dziwnie bo pracuje poprawnie jak kręcę wolno to działa licząc w lewo jak i w prawo ale najdziwniejsza sprawa że jak nie używam to w jakiś dziwny sposób zlicza w lewo (nikt niekręci pokrętłem a sam liczy). 

Enkoder podłączony jest jak na linku. 
https://zapodaj.net/1dd055f892110.png.html


Nie jestem pewien czy Piny 2,3 można używać do przerwania (Interrupt) ale wedle strony https://www.circuitstoday.com/arduino-me...schematics

[color=var(--h-color, #161616)]Hardware Interrupt Pins :[/color]

Digital pin 18 – 21,2,3 hardware interrupt is used for interrupt services. Hardware interrupt must be enabled with global interrupt enable to get interrupt from other devices.

Kod:
//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display


// przyciski
// constants won't change. They're used here to set pin numbers:
const int Button_4 = 29;     // the number of the pushbutton pin
const int Button_3 = 30;     // the number of the pushbutton pin
const int Button_2 = 31;     // the number of the pushbutton pin
const int Button_1 = 32;     // the number of the pushbutton pin

const int swiatlo = 12;

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

int buttonState_P1 = 1;
int buttonState_P2 = 0;
int buttonState_P3 = 0;
int buttonState_P4 = 0;

int Outputs_swiatlo = 0;

// enkoder

const int encoderPinA = 3;
const int encoderPinB = 2;

int angle = 0;

int encoderPos = 0;
int encoderStepsPerRevolution = 23;

boolean encoderALast = LOW; //remembers the previous state of the encoder pin A

// PWM FAN 1
//const int FAN1_SPEED_SETTING = 5;     // the number of the setting speed by PWM to pin 5 blue wire
//const int FAN1_SPEED_CONTROL = 6;     // the number of the control speed from FAN1 pin 6 yelow wire
//int count_1_pulse = 0;
//unsigned long start_time_1 = 0;
//int rpm_fan_1;


//int count = 0; //test

void setup()
{
  // FAN 1 speed
//pinMode(FAN1_SPEED_SETTING, OUTPUT);
//analogWrite(FAN1_SPEED_SETTING, 0);
//attachInterrupt(digitalPinToInterrupt(6),counter, RISING);

 
  lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(2, 0);
  lcd.print("Hello, world!");
  lcd.setCursor(4, 1);
  lcd.print("TiTa DUO!");

  // przyciski
  // initialize the pushbutton pin as an input:
  pinMode(Button_4, INPUT_PULLUP);
  pinMode(Button_3, INPUT_PULLUP);
  pinMode(Button_2, INPUT_PULLUP);
  pinMode(Button_1, INPUT_PULLUP);

  pinMode(swiatlo, OUTPUT);

  Wire.begin();
  Serial.println("pierwsze wczytanie ustawien");

  // enkoder

  pinMode(encoderPinA, INPUT_PULLUP);
  pinMode(encoderPinB, INPUT_PULLUP);
  digitalWrite(encoderPinA, HIGH);
  digitalWrite(encoderPinB, HIGH);
  Serial.begin(9600);
}

void loop()
{
//for (int pwm = 0; pwm <=255; pwm += 51){
// analogWrite(FAN1_SPEED_SETTING, pwm);
//  delay(5000);
// start_time_1 = millis();
// count = 0;
// while ((millis() - start_time_1) < 1000){
//  }
//  rpm_fan_1 = count * 30;   //60/2
//  Serial.print("PWM = ");
// Serial.print(map(pwm, 0, 255, 0, 100));
//  Serial.print("% , Speed = ");
//  Serial.print(rpm_fan_1);
//  Serial.print(" rpm");
//  }
//}

  if (buttonState_P1 == LOW) {
    lcd.clear();
    lcd.backlight();
  } //

  lcd.setCursor(2, 0);
  lcd.print("  ");
  lcd.print(encoderPos);
  lcd.print("  ");
  lcd.setCursor(10, 0);
  lcd.print("  ");
  lcd.print(angle);
  lcd.print("  ");
  // read the state of the pushbutton value:
  buttonState_P4 = digitalRead(Button_4);
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState_P4 == HIGH) {
    // turn LED on:
       Serial.println("nie_wcisniety p4");
    digitalWrite(swiatlo, LOW);
  } else {
    // turn LED off:
    Serial.println("przycisnieto p4");
    digitalWrite(swiatlo, HIGH);
  }

  // read the state of the pushbutton value:
  buttonState_P3 = digitalRead(Button_3);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState_P3 == HIGH) {
    // turn LED on:
    //    Serial.println("nie_wcisniety button 3");
  } else {
    // turn LED off:
    //    Serial.println("przycisnieto p3");
    lcd.noBacklight();    // wyłączenie podswietlenia LCD
  }

  // read the state of the pushbutton value:
  buttonState_P2 = digitalRead(Button_2);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState_P2 == HIGH) {
    // turn LED on:
    //    Serial.println("nie_wcisniety p2");
  } else {
    // turn LED off:
    //    Serial.println("przycisnieto p2");
  }

  // read the state of the pushbutton value:
  buttonState_P1 = digitalRead(Button_1);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState_P1 == HIGH) {
    // turn LED on:
    //   Serial.println("nie_wcisniety p1");
  } else {
    // turn LED off:
    Serial.println("przycisnieto p1");
    //  lcd.backlight(); // załączenie LCD
  }

  // enkoder

  boolean encoderA = digitalRead(encoderPinA);

  if ((encoderALast == HIGH) && (encoderA == LOW))
  {
    if (digitalRead(encoderPinB) == LOW)
    {
      encoderPos++;
    }
    else
    {
      encoderPos--;
    }
    angle = (encoderPos % encoderStepsPerRevolution) * 360 / encoderStepsPerRevolution;
    Serial.print(encoderPos);
    Serial.print(" ");
    Serial.println(angle);
  }
  encoderALast = encoderA;


}
// FAN 1 RPM SPEED
//void counter (){
//  count++;
//}
Na przerywaniach to też lipa z obsługą bo trzeba eliminować drgania styków, najlepiej to się robi na timerze...

Masz mój przykład powinien pasować jak masz atmegę 2560

Timer1 wykorzystuje

//////////// Encoder
#define PinB        31 //BTN_EN1 31 [RAMPS14-SMART-ADAPTER]
#define PinA        33 //BTN_EN2 33 [RAMPS14-SMART-ADAPTER]
#define PinSW      35 //BTN_ENC 35 [RAMPS14-SMART-ADAPTER]

volatile bool Old_Pin_A,Old_Pin_B,Old_Pin_SW;
volatile bool UP, DOWN, SW;

ISR(TIMER1_COMPA_vect) {
  // READ ROTARY

  bool Pin_A = digitalRead(PinA);
  bool Pin_B = digitalRead(PinB);
  bool Pin_SW = digitalRead(PinSW);

  if(Pin_A != Old_Pin_A && Pin_A) {
    if(Pin_B != Pin_A){
      UP =true;
    }
  }

  if(Pin_B != Old_Pin_B && Pin_B) {
    if(Pin_A != Pin_B){
      DOWN =true;
    }
  }

  if(Pin_SW != Old_Pin_SW){
    if(Pin_SW == LOW){
      SW = true;
    }
  }


  Old_Pin_A = Pin_A;
  Old_Pin_B = Pin_B;
  Old_Pin_SW = Pin_SW;


}

void setup(){

///////////
  pinMode (PinA,INPUT_PULLUP);
  pinMode (PinB,INPUT_PULLUP);
  pinMode (PinSW,INPUT_PULLUP);
  Old_Pin_A = digitalRead(PinA);
  Old_Pin_B = digitalRead(PinB);
  Old_Pin_SW = digitalRead(PinSW);

////////////// Timer1 encoder

  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 249;  // 1000 Hz (16000000/((249+1)*64))
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();

}

void loop(){
}




Przepinuj jak ci pasuje....
Nie bardzo rozumiem jak by to miało mi działać. Będę wdzięczny za podpowiedz. Nie stosowałem takiego timera. Zakładając że powinny zmieniać się zmienne UP, DOWN, SW by je wykorzystać do inkrementacji to u mnie to nie bardzo działa albo ja coś źle robię.
Podaj co zrobiłeś łatwiej będzie poprawic
(14-02-2022, 15:42)Jarewa0606 napisał(a): [ -> ]Podaj co zrobiłeś łatwiej będzie poprawic

Temat jest aktualny. próbowałem na kilka sposobów rozwiązać temat enkodera/zadajnika. Ostatni kod jest najlepszy ale też jest z nim problem bo zawiesza mi wykonywanie programy gdy "delikatnie pyknę pokrętło i wrócę" to program mi się nie wykonuje do momentu aż przekręcę enkoderem nawet o jeden puls. 
Kod:
//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

// dht21 (dobre)

#include "DHT.h"    // DHT biblioteka czujnika dht
#define DHT_1_PIN 11   //     || CZUJNIK UMIESZCZONY W KOOLNIERZU || // modify to the pin we connected
#define DHT_2_PIN 12   //     || CZUJNIK UMIESZCZONY W KOMOZE GÓRNY PRAWY || // modify to the pin we connected
#define DHT_3_PIN 13   //     || CZUJNIK UMIESZCZONY W KOMOZE DOLNY LEWY|| // modify to the pin we connected

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
#define DHTTYPE DHT21   // DHT 21 (AM2301)
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
DHT dht_1(DHT_1_PIN, DHTTYPE);      // P2 DHT 1 KOLNIERZ
DHT dht_2(DHT_2_PIN, DHTTYPE);      // P3 DHT 3 DOLNY LEWY
DHT dht_3(DHT_3_PIN, DHTTYPE);      // P4 DHT 2 GORNY PRAWY
// koniec test dht 21 (dobre)


// ------------------- >> INA219 pomiar U/I void before setup

// #include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;

// ------------------- >> KONIEC  INA219 pomiar U/I void before setup






// ----------------------------------------------->> pinout <<-----------------------------------------------
// inputs (dobre)
// constants won't change. They're used here to set pin numbers:


const unsigned int drzwi_1 = 26;  // the number of the pushbutton pin        // przewód rózowy „zamke drzwi prawy dolny” wejscie na przekaźnik drzwi_1
const unsigned int drzwi_2 = 27;  // the number of the pushbutton pin        // przewód szary „zamek lewy dolny” wejscie na przekaźnik drzwi_2
const unsigned int drzwi_3 = 28;  // the number of the pushbutton pin        // przewód fioletowy „zamek górny drzwi” wejscie na przekaźnik drzwi_3
const unsigned int Button_4 = 29;     // the number of the pushbutton pin    // przycisk P1 - na samej górze
const unsigned int Button_3 = 30;     // the number of the pushbutton pin    // przycisk P2 - na dole pierwszy od lewej
const unsigned int Button_2 = 31;     // the number of the pushbutton pin    // przycisk P3 - na dole środkowy od lewej
const unsigned int Button_1 = 32;     // the number of the pushbutton pin    // przycisk P4 - na dole ostatni/trzeci od lewej
const unsigned int Button_encoder = 33;     // the number of the pushbutton pin    // przycisk enkodera inkrementalnego

// Outpputs (dobre)
const unsigned int swiatlo = 4;  // the number of the pushbutton pin        // przewód Biało/czerwony wyjscie na moduł MOS-Ch1
const unsigned int buzzer = 34; // BUZER/ALARM // the number of the pushbutton pin        // przewód Biało/czerwony wyjscie na moduł MOS-Ch1


// koniec przyciski (dobre)
// ----------------------------------------------->> pinout <<-----------------------------------------------

// variables will change:

int unsigned doorState_1 = 0;   // drzwi przekaznik 1                        // przewód rózowy „zamke drzwi prawy dolny” wejscie na przekaźnik drzwi_1
int unsigned doorState_2 = 0;   // drzwi przekaznik 2                        // przewód szary „zamek lewy dolny” wejscie na przekaźnik drzwi_2
int unsigned doorState_3 = 0;   // drzwi przekaznik 3                        // przewód fioletowy „zamek górny drzwi” wejscie na przekaźnik drzwi_3

int unsigned buttonState = 0;         // variable for reading the pushbutton status

int unsigned buttonState_P1 = 1;   // przycisk P1 - na samej górze
int unsigned buttonState_P2 = 0;   // przycisk P2 - na dole pierwszy od lewej
int unsigned buttonState_P3 = 0;   // przycisk P3 - na dole środkowy od lewej
int unsigned buttonState_P4 = 0;   // przycisk P4 - na dole ostatni/trzeci od lewej        // by niemigalo swiatlo po uruchomieniu
int unsigned buttonState_encoder = 0;   // przycisk enkodera inkrementalnego

int unsigned Outputs_swiatlo = 0; // oswietlenie komory cieplarki

// enkoder
int encoderPos = 0;
int encoderStepsPerRevolution = 20;
int angle = 0;

// enkoder no
#define PinA 2 
#define PinB 3 

unsigned long time = 0;
long count = 0;
long num = 0;
// enkoder nowy koniec

int unsigned Timer_1 =0;
int unsigned Timer_2 =0;

// PWM FAN 1
//const int FAN1_interupt = 19;     // the number of the setting speed by PWM to pin 5 blue wire
//const int FAN1_SPEED_SETTING = 5;     // the number of the control speed from FAN1 pin 6 yelow wire
//const int FAN2_SPEED_SETTING = 7;     // the number of the control speed from FAN1 pin 6 yelow wire
//int count_1_pulse = 0;
//unsigned long start_time_1 = 0;
//int rpm_fan_1;



// // PWM FAN 1 i 2 timer + interupt v1.01
//
unsigned long last1 = 0;
unsigned long last2 = 0;
unsigned long lasts = 0;
unsigned int dur1 = 0;
unsigned int dur2 = 0;
byte tgt1 = 255;    //  ||51-20%|102-40%|153-60%|204-80%|255-100%||    // ustawianie parametrow predkosci
byte tgt2 = 255;           // ustawianie parametrow predkosci


//----------------------------------------------- INFO -----------------------------------------
// interupt input in arduino mega 2560

//INTX    ->    chip pin    -    mega pin
//INT0    ->    43          -    21
//INT1    ->    44          -    20
//INT2    ->    45          -    19
//INT3    ->    46          -    18
//INT4    ->    6           -    2
//INT5    ->    7           -    3

// INFO:Digital Pins With Interrupts
//Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21
//(pins 20 & 21 are not available to use for interrupts while they are used for I2C communication)
// zrodlo: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
//----------------------------------------------- INFO -----------------------------------------

// koniec PWM FAN 1 i 2 timer + interupt v1.01

// BUZZER

boolean Activate_Alarm = false;     // deklaracja zmiennej bool dla buzzer
unsigned alarm_status = 0;    // numer alarmu czytany po bitach (złożenie słowa) zakresu od 0 do 65535

void setup()
{

//if (Timer_1 >= 100){

// --------------------------------------->> INA219 pomiar U/I void  setup
while (!Serial) {
      // will pause Zero, Leonardo, etc until serial console opens
//     delay(1);

  }

  uint32_t currentFrequency;

if (! ina219.begin()) {
    Serial.println("Failed to find INA219 chip");
    while (1) { Timer_2 = Timer_2++;      // zamiast delay(1);
    if (Timer_2 >= 50) {Timer_2 =0;} }
  }
  // To use a slightly lower 32V, 1A range (higher precision on amps):
  //ina219.setCalibration_32V_1A();
  // Or to use a lower 16V, 400mA range (higher precision on volts and amps):
  //ina219.setCalibration_16V_400mA();
// }
  Serial.println("Measuring voltage and current with INA219 ...");

// --------------------------------------->> koniec  INA219 pomiar U/I void  setup

 
  // testy FAN1 i FAN2 timer + interupt v1.01

  Serial.begin(115200);
  pinMode(18, INPUT_PULLUP);
  pinMode(19, INPUT_PULLUP);
  pinMode(50, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(18), tacho1, FALLING);
  attachInterrupt(digitalPinToInterrupt(19), tacho2, FALLING);

  //Timer 1: Prescaler 0
  TCCR1B = TCCR1B & B11111000 | B00000001;

  analogWrite(7, tgt1);   // amienione ze sztywnych wartosci
  analogWrite(5, tgt2);   // zmienione ze sztywnych wartosci



  // koniec testy FAN1 i FAN2 timer + interupt v1.01


  // test pwm fan 1 and 2
  // FAN 1 speed

  //pinMode(FAN1_SPEED_SETTING, OUTPUT);
  //pinMode(FAN2_SPEED_SETTING, OUTPUT);

  //pinMode(FAN1_interupt, INPUT_PULLUP);
  //analogWrite(FAN1_SPEED_SETTING, 0);
  //Serial.begin(9600);
  // attachInterrupt(digitalPinToInterrupt(FAN1_interupt), count_1, RISING);
  // koniec test pwm fan 1

  lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  lcd.backlight();
  //  lcd.setCursor(2, 0);
  //  lcd.print("Hello, world!");
  lcd.setCursor(4, 1);
  lcd.print("TiTa DUO!");

  // inputs (dobre)
  // initialize the pushbutton pin as an input:
  pinMode(Button_encoder, INPUT_PULLUP);
  pinMode(Button_4, INPUT_PULLUP);
  pinMode(Button_3, INPUT_PULLUP);
  pinMode(Button_2, INPUT_PULLUP);
  pinMode(Button_1, INPUT_PULLUP);
  pinMode(drzwi_1, INPUT_PULLUP);
  pinMode(drzwi_2, INPUT_PULLUP);
  pinMode(drzwi_3, INPUT_PULLUP);
  // koniec inputs (dobre)

  // outputs (dobre)
  pinMode(swiatlo, OUTPUT);
  pinMode(buzzer, OUTPUT);

  // koniec outputs (dobre)

  Wire.begin();
  Serial.println("pierwsze wczytanie ustawien");

// enkoder nowy 
pinMode(PinA,INPUT_PULLUP);
pinMode(PinB,INPUT_PULLUP);

attachInterrupt(0, blinkA, LOW); 
attachInterrupt(1, blinkB, LOW); 

time = millis();

// enkoder koniec

  // dht 21 (dobre)
  Serial.println("DHTxx test!");
  dht_1.begin();
  dht_2.begin();
  dht_3.begin();
  // dht 21 koniec (dobre)

}
void getPwm(byte &val) {
  byte tmp = Serial.parseInt();
  if (tmp > 0) val = map(tmp, 0, 100, 0, 255);
}
void loop()
{

// --------------------------------->>>>>  INA219 pomiar U/I void loop

float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;
  float power_mW = 0;

  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);

Timer_1 == Timer_1 ++;
if (Timer_1 >= 100){

  Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
  Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
  Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
  Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
  Serial.print("Power:         "); Serial.print(power_mW); Serial.println(" mW");
  Serial.println("");
Timer_1 = 0;
// delay(20);
}
// ---------->>> INA219 pomiar U/I void loop




  light();    // wywołanie bloku oświetlenia
  buzzer_alarm();    // wywolanie bloku dla buzzer

  // drzwi test (dobre)
  doorState_1 = digitalRead(drzwi_1);
  doorState_2 = digitalRead(drzwi_2);
  doorState_3 = digitalRead(drzwi_3);

  // drzwi koniec test (dobre)

  // testowe inputs drzwi Ch1 (dobre)
  //if (doorState_1 == HIGH) {
  //Serial.println("drzwi zamkniete ch1");
  //  } else {
  //Serial.println("drzwi otwarte ch1");
  //  }

  // testowe inputs drzwi Ch2 (dobre)
  //if (doorState_2 == HIGH) {
  //Serial.println("drzwi zamkniete ch2");
  //  } else {
  //Serial.println("drzwi otwarte ch2");
  //  }

  // testowe inputs drzwi Ch3 (dobre)
  //if (doorState_3 == HIGH) {
  //Serial.println("drzwi zamkniete ch3");
  //  } else {
  //Serial.println("drzwi otwarte ch3");
  //  }

  // koniec testowe inputs drzwi (dobre)

  // TESTOWE INPUTS
  // if (buttonState_P1 == HIGH) {
  // turn LED on:
  //   Serial.println("nie_wcisniety p1");
  //  } else {
  //    // turn LED off:
  //    Serial.println("przycisnieto p1");
  //    //  lcd.backlight(); // załączenie LCD
  //}
  // KONIEC TESTOWE INPUTS

  // Test fan 1 i fan 2 timer + interupt v1.01

  unsigned long cm = millis();

  if (Serial.available()) {
    byte tmp = Serial.parseInt();
    switch (tmp) {
      case 1:
        getPwm(tgt1);
        break;
      case 2:
        getPwm(tgt2);
        break;
    }
  }

  if (lasts > cm || (lasts + 1000) < cm) {
    digitalWrite(50, !digitalRead(50));
    Serial.print("Delay1: ");
    Serial.print(dur1);
    Serial.println("µs");

    unsigned long freq = 100000000 / dur1;
    Serial.print("Frequenz1: ");
    Serial.print(freq / 100);
    Serial.print('.');
    Serial.print(freq % 100);
    Serial.println("Hz");

    freq *= 60;
    freq /= 200;
    Serial.print("RPM1: ");
    Serial.println(freq);


    Serial.print("Ziel1: ");      // zel to % wypełnienia PWM
    Serial.print(map(tgt1, 0, 255, 0, 100));
    Serial.println('%');


    Serial.print("Delay2: ");
    Serial.print(dur2);
    Serial.println("µs");

    freq = 100000000 / dur2;
    Serial.print("Frequenz2: ");
    Serial.print(freq / 100);
    Serial.print('.');
    Serial.print(freq % 100);
    Serial.println("Hz");

    freq *= 60;
    freq /= 200;
    Serial.print("RPM2: ");
    Serial.println(freq);


    Serial.print("Ziel2: ");      // zel to % wypełnienia PWM
    Serial.print(map(tgt2, 0, 255, 0, 100));
    Serial.println('%');

    Serial.println("-----");
    lasts = millis();
  }

  analogWrite(9, tgt1);
  analogWrite(10, tgt2);



  // test zalaczenie podswietlania mozna przeniesc do linijek nizej
  if (buttonState_P1 == LOW) {
    lcd.clear();
    lcd.backlight();
    // FAN1_SPEED_SETTING_PWM = 204;
    //   FAN2_SPEED_SETTING_PWM = 204;

  } //

  lcd.setCursor(2, 0);
  lcd.print("  ");
  lcd.print(encoderPos);
  lcd.print("  ");
  lcd.setCursor(10, 0);
  lcd.print("  ");
  lcd.print(angle);
  lcd.print("  ");

 
  // read the state of the pushbutton value:

  buttonState_P4 = digitalRead(Button_4);
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState_P4 == HIGH) {
    // turn LED on:
    // Serial.println("nie_wcisniety p4");

    //   FAN1_SPEED_SETTING_PWM = 51;
    //   FAN2_SPEED_SETTING_PWM = 51;
  } else {
    // turn LED off:
//   Serial.println("przycisnieto p4");

    // FAN1_SPEED_SETTING_PWM = 255;
    // FAN2_SPEED_SETTING_PWM = 255;

    // dth21_2 (dobre)
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht_2.readHumidity();
    float t = dht_2.readTemperature();
    // check if returns are valid, if they are NaN (not a number) then something went wrong!
    if (isnan(t) || isnan(h)) {
      Serial.println("Failed to read from DHT");
    } else {
      Serial.print("|| CZUJNIK UMIESZCZONY W KOMOZE GÓRNY PRAWY ||");
      Serial.print("Humidity: ");
      Serial.print(h);
      Serial.print(" %\t");
      Serial.print("Temperature: ");
      Serial.print(t);
      Serial.println(" *C");
    }
    // dht 21_2 (dobre)

  }

  // read the state of the pushbutton value:
  buttonState_P3 = digitalRead(Button_3);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState_P3 == HIGH) {
    // turn LED on:
    //    Serial.println("nie_wcisniety button 3");
  } else {
    // turn LED off:
    //    Serial.println("przycisnieto p3");
    lcd.noBacklight();    // wyłączenie podswietlenia LCD

    // dth21_3 (dobre)
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht_3.readHumidity();
    float t = dht_3.readTemperature();
    // check if returns are valid, if they are NaN (not a number) then something went wrong!
    if (isnan(t) || isnan(h)) {
      Serial.println("Failed to read from DHT");
    } else {
      Serial.print("|| CZUJNIK UMIESZCZONY przycisnieto p3");
      Serial.print("Humidity: ");
      Serial.print(h);
      Serial.print(" %\t");
      Serial.print("Temperature: ");
      Serial.print(t);
      Serial.println(" *C");
    }
    // dht 21_3 (dobre)

  }

buttonState_encoder = digitalRead(Button_encoder);
  if (buttonState_encoder == HIGH) {
    // turn LED on:
//     Serial.println("enkoder klik nie wcisniety");
  //  digitalWrite(swiatlo, LOW);
  } else {
    // turn LED off:
    Serial.println("enkoder klik wcisniety");
    //  lcd.backlight(); // załączenie LCD
  //  digitalWrite(swiatlo, HIGH);
  }

  // read the state of the pushbutton value:
  buttonState_P2 = digitalRead(Button_2);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState_P2 == HIGH) {

    // turn LED on:
    //    Serial.println("nie_wcisniety p2");
  } else {
    // turn LED off:
//       Serial.println("przycisnieto p2");

    // dth21_1 (dobre)
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht_1.readHumidity();
    float t = dht_1.readTemperature();
    // check if returns are valid, if they are NaN (not a number) then something went wrong!
    if (isnan(t) || isnan(h)) {
      Serial.println("Failed to read from DHT");
    } else {
      Serial.print("|| CZUJNIK UMIESZCZONY W KOOLNIERZU ||");
      Serial.print("Humidity: ");
      Serial.print(h);
      Serial.print(" %\t");
      Serial.print("Temperature: ");
      Serial.print(t);
      Serial.println(" *C");

      // FAN1_SPEED_SETTING_PWM = 102;
      //   FAN2_SPEED_SETTING_PWM = 102;

    }
    // dht 21_1 koniec (dobre)

  }

  // read the state of the pushbutton value:
  buttonState_P1 = digitalRead(Button_1);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState_P1 == HIGH) {
    // turn LED on:
    //   Serial.println("nie_wcisniety p1");
//    digitalWrite(buzzer, LOW);
  } else {
    // turn LED off:
//   Serial.println("przycisnieto p1");
    //  lcd.backlight(); // załączenie LCD
//    digitalWrite(buzzer, HIGH);
  }

// enkoder nowy

while (encoderPos != count)
{
   encoderPos = count;
   Serial.println(encoderPos);

   //test nowy enkoder
angle = (encoderPos % encoderStepsPerRevolution) * 360 / encoderStepsPerRevolution;
    Serial.print(encoderPos);
    Serial.print(" ");
    Serial.println(angle);
}


// enkoder nowy

}

//enkoder nowy

void blinkA()
{
if ((millis() - time) > 5)
       count ++;
time = millis();
}

void blinkB()
{
if ((millis() - time) > 5) 
       count --;
time = millis();
}
//koniec enkoder nowy

void light() {
  // drzwi koniec test (dobre)

  // testowe inputs drzwi Ch1 (dobre)
  if (doorState_1 == HIGH || doorState_2 == HIGH || buttonState_P1 == LOW) {
    digitalWrite(swiatlo, HIGH);
    // Serial.println("drzwi zamkniete ch1");
  } else {
    digitalWrite(swiatlo, LOW);
    //Serial.println("drzwi otwarte ch1");
  }

  // testowe inputs drzwi Ch2 (dobre)
  //if (doorState_2 == HIGH) {
  //Serial.println("drzwi zamkniete ch2");
  //  } else {
  //Serial.println("drzwi otwarte ch2");
  //  }

  // testowe inputs drzwi Ch3 (dobre)
  //if (doorState_3 == HIGH) {
  //Serial.println("drzwi zamkniete ch3");
  //  } else {
  //Serial.println("drzwi otwarte ch3");
  //  }
}

// test fan 1 i fan 2 timer + interupt
void tacho1() {
  unsigned long cm = micros();
  dur1 = (cm - last1);
  last1 = cm;
}

void tacho2() {
  unsigned long cm = micros();
  dur2 = (cm - last2);
  last2 = cm;
}
  // https://gist.github.com/adlerweb/fab155592dac2dd0acdfbb9db373de67
  // koniec test fan 1 i fan 2 timer + interupt

 
void buzzer_alarm() {
  alarm_status = alarm_status;
  // zalaczenie sygnalu dzwiekowego                ----->> ALARM DZWIEKOWY <<-------
  if (Activate_Alarm == true || (buttonState_P2 == LOW && buttonState_P4 == LOW)) {
    digitalWrite(buzzer, HIGH);
 
   
  }
  else {
    digitalWrite(buzzer, LOW);

  }
}

// 03.03.2022_22:30 - jakiś inny pomysł na enkoder/zadajnik inkrementalny na arduino mega 2560 ? wszelkiego rady i sugestię mile widziane w temacie enkodera/zadajnika bo to on jest problemem obecnie.

//10.03.2022_23:30 - problem pojawia się gdy enkoder zatrzymam pomiędzy kanałami - enkoder na pewno jest ok. Może jak bym wstawił enkoder z większą ilością pulsów na obrót to bym może jakoś to rozwiązał. Wszelakie propozycje rozwiązania problemu mile widziane.