ШИМ и Серво

Alexei39
Offline
Зарегистрирован: 26.03.2016

#include <Servo.h>
Servo myservo;
  
void setup() {
  myservo.attach(3);
  pinMode(10, OUTPUT);
}

void loop() {
  int reading1 = analogRead(1);
  int val = reading1 / 4;
  analogWrite(10, val);
  int val1 = analogRead(0);
  int x = val1 / 6;
  myservo.write(x);
}

Всем сдравствуйте. Подскажите как заставить работать ШИМ и Сервомотор в одной программе

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/*
  #1 Серва1 упр. выв -> 12    (servo1_pin)
               +5В -> +5В
               GND -> GND
  #2 резистор  нижний выв   -> GND
             средний выв  -> A0    (R1_pin)
             верхний выв  -> +5
*/
//#1
const int servo1_pin = 12;
uint16_t servo1_value = 544 ; // величина на серве 544-2400 мкс.
uint8_t servo1;//

//#2
const int R1_pin = A0;// нога резистора

void setup() {
  //#1
  pinMode      (servo1_pin, OUTPUT);
  digitalWrite (servo1_pin, servo1 = 0);
  //#2
}
void loop() {
  //#1 20 миллисекунд обслуживание сервы 1 и 2
  static uint32_t past_1 = 0 ;
  if  (servo1 && (micros() - past_1 >= servo1_value))
    digitalWrite (servo1_pin, servo1 = 0);
  if (micros() - past_1 >= 20000) { // если прошло 20000 микросек //  это автозапуск импульса
    past_1 = micros() ;                                           // вставьте эти команды в прерывание
    digitalWrite (servo1_pin, servo1 = 1);                        // и будет вам формирование нужного импульса 
  }                                                               // при освобождении процессора
  //#2
  static uint32_t past_2 = 0 ;
  if (millis() - past_2 >= 200) { // если прошло 200000 микросек
    past_2 = millis() ;
    servo1_value = map (analogRead(R1_pin), 0, 1023, 544, 2400);
  }
}

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

Спасибо за ответ. Если я правельно понял в вашем коде управление только сервомотором

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

Все эта идея задумывалась Для управление печкой.

Сервомоторы управляют заслонками. Это все работает. Но не работает мотор винтелятора. ВОт мой код.

#include <Servo.h>
String readString, servo1, servo2, servo3,servo4;
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;
int kn1 = 2;
int kn2 = 4;
int kn3 = 7;
int kn4 = 8;
int potPin1 = 0;
int potPin2 = 1;

void setup() {
  Serial.begin(9600); 
 myservo1.attach(3);
 myservo2.attach(5);
 myservo3.attach(6);
 myservo4.attach(9);
 pinMode(kn1, INPUT);
 pinMode(kn2, INPUT);
 pinMode(kn3, INPUT);
 pinMode(kn4, INPUT);
 pinMode(10, OUTPUT);
}

void loop() {
  int reading = analogRead(potPin1);
  int angle = reading / 6;
  myservo1.write(angle);
  int reading1 = analogRead(potPin2);
  int val = reading1 / 4;
  Serial.println(val);
  analogWrite(10, val);
  
  if (digitalRead(kn4) == HIGH)
      { myservo2.write(150);}
    else { myservo2.write(30);}
  if (digitalRead(kn2) == HIGH)
      { myservo3.write(150);}
    else { myservo3.write(30);}
  if (digitalRead(kn1) == HIGH && digitalRead(kn3) == HIGH)
      { myservo4.write(90);}
  if (digitalRead(kn1) == LOW && digitalRead(kn3) == LOW)
      { myservo4.write(90);}
  if (digitalRead(kn1) == LOW && digitalRead(kn3) == HIGH)
      { myservo4.write(10);}
  if (digitalRead(kn1) == HIGH && digitalRead(kn3) == LOW)
      { myservo4.write(170);}
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Скорее у вас зевок в схеме.  Замените оптрон светодиодом у проверьте ШИМ программы.

Мне кажется , но для сервы шимированые выхода не обязательны.

Alexei39
Offline
Зарегистрирован: 26.03.2016

Ура разобрался. Рересодил шим на 11 ногу и все зароботало

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

#include <Servo.h>
String readString, servo1, servo2, servo3,servo4;
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;
int kn1 = 2;
int kn2 = 4;
int kn3 = 7;
int kn4 = 8;
int potPin1 = 0;
int potPin2 = 1;

void setup() {
 myservo1.attach(3);
 myservo2.attach(5);
 myservo3.attach(6);
 myservo4.attach(9);
 pinMode(kn1, INPUT);
 pinMode(kn2, INPUT);
 pinMode(kn3, INPUT);
 pinMode(kn4, INPUT);
 pinMode(11, OUTPUT);
 pinMode(1, OUTPUT);
 pinMode(0, OUTPUT);
 pinMode(12, OUTPUT);
}

void loop() {
  int reading = analogRead(potPin1);
  int angle = reading / 6;
  if (angle <= 10)
      { digitalWrite (12, LOW);}
      else {digitalWrite (12, HIGH);} 
    myservo1.write(angle);
    int reading1 = analogRead(potPin2);
  int val = reading1 / 4;
  analogWrite(11, val);
  
  if (digitalRead(kn4) == HIGH)
      { myservo2.write(150);}
    else { myservo2.write(30);}
  if (digitalRead(kn2) == HIGH)
      { myservo3.write(150);}
    else { myservo3.write(30);}
  if (digitalRead(kn1) == HIGH && digitalRead(kn3) == HIGH)
      { myservo4.write(90);}
  if (digitalRead(kn1) == LOW && digitalRead(kn3) == LOW)
      { myservo4.write(90);}
  if (digitalRead(kn1) == LOW && digitalRead(kn3) == HIGH)
      { myservo4.write(10);}
  if (digitalRead(kn1) == HIGH && digitalRead(kn3) == LOW)
      { myservo4.write(170);}
}

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

qwone, 

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Похоже придется запускать программу по частям. Тем более мне работа схемы не понятно. Пожалуста составьте снова ТЗ или опишите работу устройства.

Alexei39
Offline
Зарегистрирован: 26.03.2016

https://yadi.sk/d/Tcy7zWdm3JKcGY

Это сылка на файл в протеусе и ipg постарался зделать с хорошим расирением

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

Кнопка regim меняет выбор управления вентилятором или заслонкой горечо холодно, а также она при длительном нажатии выключает печку и включает.

Энкодер скорость вентилятора или положение заслонки гор хол

кнопка sb recirkul управляет моторчиком recirkul у него 2 положения закрыто или открыто.

кнопка obogrev алгоритм ее ты уже написал.

Реле (насос кран RL5) выключена когда заслонка в первом положение,а в остальных включена.

вроде все описал

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Погоняй этот код 

/*Cl_74HC595.ino

*/
//--------------------class Cl_wire_74HC595------------------------
class Cl_wire_74HC595 {
    byte Latch_pin; // вывод Latch
    byte CLK_pin;   // вывод CLK
    byte Data_pin;  // вывод Data
    byte max_device;  // количество 74HC595 в шине
    byte * buffer;
  public:
    Cl_wire_74HC595 *pnt = NULL;
    // коструктор
    Cl_wire_74HC595(byte Latch, byte CLK, byte Data, byte device)
      : Latch_pin(Latch), CLK_pin(CLK), Data_pin(Data), max_device(device) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      buffer = new byte[max_device];
      pinMode(Latch_pin, OUTPUT);
      pinMode(CLK_pin, OUTPUT);
      pinMode(Data_pin, OUTPUT);
      digitalWrite(Latch_pin, LOW);
      for (int i = max_device; i > 0; i--)
        shiftOut(Data_pin, CLK_pin, MSBFIRST, (*(buffer + i - 1) = 0));
      digitalWrite(Latch_pin, HIGH);
    }
    // отправка байта в шину на опред микросх
    void transferOut(byte adr, byte data) {
      if (adr == 0 || adr > max_device)return;
      *(buffer + adr - 1) = data;
      digitalWrite(Latch_pin, LOW);
      for (int i = max_device; i > 0; i--)
        shiftOut(Data_pin, CLK_pin, MSBFIRST, *(buffer + i - 1));
      digitalWrite(Latch_pin, HIGH);
    }
    // отправка бита в шину на опред вывод опред микросх
    void transferOut(byte adr, byte bit, bool data) {
      if (adr == 0 || adr > max_device)return;
      if (bit > 7)return;
      (data) ? *(buffer + adr - 1)  |= (1UL << (bit)) : *(buffer + adr - 1)  &= ~(1UL << (bit));// bitSet :bitClear
      digitalWrite(Latch_pin, LOW);
      for (int i = max_device; i > 0; i--)
        shiftOut(Data_pin, CLK_pin, MSBFIRST, *(buffer + i - 1));
      digitalWrite(Latch_pin, HIGH);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
};
//--------------------class Cl_74HC595------------------------
class Cl_74HC595 {
    Cl_wire_74HC595 *wire;
    byte adr; // адрес микросхемы в шине
  public:
    Cl_74HC595 *pnt = NULL;
    // конструктор  (шина,позиция в шине 1..5)
    Cl_74HC595(Cl_wire_74HC595 *_wire, byte _adr)
      : wire(_wire), adr(_adr) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      wire->transferOut(adr, 0x00);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(byte data) {
      wire->transferOut(adr, data);
    }
};
//-----------------class Cl_sys---------------------------
class Cl_sys {
    Cl_wire_74HC595 * Start_W_74HC595   = NULL; // шина 74HC595
    Cl_74HC595      * Start_74HC595     = NULL; // 74HC595 на шине
  public:
    Cl_sys() {};
    void setup() {
      Start_W_74HC595   ->setup();
      Start_74HC595     ->setup();

    }
    void loop() {
      Start_W_74HC595   ->loop();
      Start_74HC595     ->loop();

    }
    void Plug(Cl_wire_74HC595 * W_74HC595) { // подключить шину из 74HC595
      W_74HC595->pnt  = Start_W_74HC595;
      Start_W_74HC595 = W_74HC595;
    }
    void Plug(Cl_74HC595 *_74HC595) {         // подключить 74HC595 на шине
      _74HC595->pnt = Start_74HC595;
      Start_74HC595 = _74HC595;
    }
};
//--------------------------------------------
//шинa74HC595 Latch=7,CLK=8,Data=12,device=3
Cl_wire_74HC595 Wire(7, 8, 12, 3); // подключить шину на выв 2
Cl_74HC595 _74HC595_U3(&Wire, 1); // подключить шину 74HC595_N1 адр=1
Cl_74HC595 _74HC595_U2(&Wire, 2); // подключить шину 74HC595_N2 адр=2
Cl_74HC595 _74HC595_U1(&Wire, 3); // подключить шину 74HC595_N2 адр=3
Cl_sys Sys;

void setup() {
  Sys.Plug(&Wire);
  Sys.Plug(&_74HC595_U3);
  Sys.Plug(&_74HC595_U2);
  Sys.Plug(&_74HC595_U1);
  _74HC595_U1.write(0x00); //<------
  _74HC595_U2.write(0x0F); //<------ меняй значения. Тогда значения на выв 74HC595 будут меняться
  _74HC595_U3.write(0xFF); //<------
  Sys.setup();
}
void loop() {
  Sys.loop();
}

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

Не работает на выходах 74HC595 тишина

Alexei39
Offline
Зарегистрирован: 26.03.2016

А у тебя протеус есть?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

криво работает.вчера поставил.раньше не работал

Alexei39
Offline
Зарегистрирован: 26.03.2016

А какой ставишь у меня восмой тоже не на всех компах идет. Я все на семерке он под любой вндой работает

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вот еще код. Посмотри 

/*Cl_74HC595.ino

*/
//--------------------class Cl_wire_74HC595------------------------
class Cl_wire_74HC595 {
    byte Latch_pin; // вывод Latch
    byte CLK_pin;   // вывод CLK
    byte Data_pin;  // вывод Data
    byte max_device = 0; // количество 74HC595 в шине
    byte * buffer;
  public:
    Cl_wire_74HC595 *pnt = NULL;
    // коструктор
    Cl_wire_74HC595(byte Latch, byte CLK, byte Data, byte device)
      : Latch_pin(Latch), CLK_pin(CLK), Data_pin(Data), max_device(device) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      buffer = new byte[max_device];
      pinMode(Latch_pin, OUTPUT);
      pinMode(CLK_pin, OUTPUT);
      pinMode(Data_pin, OUTPUT);
      for (int i = 0; i > max_device; i++) transferOut(i, 0x00);
    }
    // отправка байта в шину на опред микросх
    //              adr 0,1,.  data byte
    void transferOut(byte adr, byte data) {
      if (adr == 0 || adr > max_device)return;
      if (max_device == 0) return;
      *(buffer + adr) = data;
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device - 1; j >= 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(*(buffer + j) & (1 << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // отправка бита в шину на опред вывод опред микросх
    //              adr 0,1,..  _bit 0,1,..  data 0,1
    void transferOut(byte adr, byte _bit, bool data) {
      if (adr == 0 || adr > max_device)return;
      if (_bit > 7)return;
      if (max_device == 0) return;
      (data) ? *(buffer + adr)  |= (1UL << _bit) : *(buffer + adr)  &= ~(1UL << _bit);// bitSet :bitClear
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device - 1; j >= 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(*(buffer + j) & (1UL << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
};
//--------------------class Cl_74HC595------------------------
class Cl_74HC595 {
    Cl_wire_74HC595 *wire;
    byte adr; // адрес микросхемы в шине
  public:
    Cl_74HC595 *pnt = NULL;
    // конструктор  (шина,позиция в шине 1..5)
    Cl_74HC595(Cl_wire_74HC595 *_wire, byte _adr)
      : wire(_wire), adr(_adr) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      wire->transferOut(adr, 0x00);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(byte data) {
      wire->transferOut(adr, data);
    }
};
//-----------------class Cl_sys---------------------------
class Cl_sys {
    Cl_wire_74HC595 * Start_W_74HC595   = NULL; // шина 74HC595
    Cl_74HC595      * Start_74HC595     = NULL; // 74HC595 на шине
  public:
    Cl_sys() {};
    void setup() {
      Start_W_74HC595   ->setup();
      Start_74HC595     ->setup();

    }
    void loop() {
      Start_W_74HC595   ->loop();
      Start_74HC595     ->loop();

    }
    void Plug(Cl_wire_74HC595 * W_74HC595) { // подключить шину из 74HC595
      W_74HC595->pnt  = Start_W_74HC595;
      Start_W_74HC595 = W_74HC595;
    }
    void Plug(Cl_74HC595 *_74HC595) {         // подключить 74HC595 на шине
      _74HC595->pnt = Start_74HC595;
      Start_74HC595 = _74HC595;
    }
};
//--------------------------------------------
//шинa74HC595 Latch=7,CLK=8,Data=12,device=3
Cl_wire_74HC595 Wire(7, 8, 12, 3); // подключить шину на выв 2
Cl_74HC595 _74HC595_U3(&Wire, 0); // подключить шину 74HC595_N1 адр=0
Cl_74HC595 _74HC595_U2(&Wire, 1); // подключить шину 74HC595_N2 адр=1
Cl_74HC595 _74HC595_U1(&Wire, 2); // подключить шину 74HC595_N2 адр=2
Cl_sys Sys;

void setup() {
  Sys.Plug(&Wire);
  Sys.Plug(&_74HC595_U3);
  Sys.Plug(&_74HC595_U2);
  Sys.Plug(&_74HC595_U1);
  Sys.setup();
}
void loop() {
  static uint32_t past = 0;
  static byte a = 0x55;
  if (millis() - past > 300) {
    _74HC595_U1.write(a = ~a);
    _74HC595_U2.write(a);
    _74HC595_U3.write(a);
  }
  Sys.loop();
}

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

qwone,

Спасибо за твою работу. Но опять без результатно светодиоды просто мегают в хаотичном порядке

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Здесь они должны мигать в организованом порядке 

/*Cl_74HC595.ino

*/
//--------------------class Cl_wire_74HC595------------------------
class Cl_wire_74HC595 {
    byte Latch_pin; // вывод Latch
    byte CLK_pin;   // вывод CLK
    byte Data_pin;  // вывод Data
    byte max_device = 0; // количество 74HC595 в шине
    byte * buffer;// использовать начиная buffer[1],buffer[2],..
  public:
    Cl_wire_74HC595 *pnt = NULL;
    // коструктор
    Cl_wire_74HC595(byte Latch, byte CLK, byte Data, byte device)
      : Latch_pin(Latch), CLK_pin(CLK), Data_pin(Data), max_device(device) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      buffer = new byte[max_device + 1];
      pinMode(Latch_pin, OUTPUT);
      pinMode(CLK_pin, OUTPUT);
      pinMode(Data_pin, OUTPUT);
      for (int i = 0; i > max_device; i++) transferOut(i, 0x00);
    }
    // отправка байта в шину на опред микросх
    //              adr 1,2.  data byte
    void transferOut(byte adr, byte data) {
      if (adr == 0 || adr > max_device)return;
      if (max_device == 0) return;
      buffer[adr] = data;
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device ; j > 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(buffer[j] & (1UL << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // отправка бита в шину на опред вывод опред микросх
    //              adr 1,2,..  _bit 0,1,..  data 0,1
    void transferOut(byte adr, byte _bit, bool data) {
      if (adr == 0 || adr > max_device)return;
      if (_bit > 7)return;
      if (max_device == 0) return;
      (data) ? buffer[adr]  |= (1UL << _bit) : buffer[adr]  &= ~(1UL << _bit);// bitSet :bitClear
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device ; j > 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(buffer[j] & (1UL << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
};
//--------------------class Cl_74HC595------------------------
class Cl_74HC595 {
    Cl_wire_74HC595 *wire;
    byte adr; // адрес микросхемы в шине
  public:
    Cl_74HC595 *pnt = NULL;
    // конструктор  (шина,позиция в шине 1..5)
    Cl_74HC595(Cl_wire_74HC595 *_wire, byte _adr)
      : wire(_wire), adr(_adr) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      wire->transferOut(adr, 0x00);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(byte data) {
      wire->transferOut(adr, data);
    }
};
//-----------------class Cl_sys---------------------------
class Cl_sys {
    Cl_wire_74HC595 * Start_W_74HC595   = NULL; // шина 74HC595
    Cl_74HC595      * Start_74HC595     = NULL; // 74HC595 на шине
  public:
    Cl_sys() {};
    void setup() {
      Start_W_74HC595   ->setup();
      Start_74HC595     ->setup();

    }
    void loop() {
      Start_W_74HC595   ->loop();
      Start_74HC595     ->loop();

    }
    void Plug(Cl_wire_74HC595 * W_74HC595) { // подключить шину из 74HC595
      W_74HC595->pnt  = Start_W_74HC595;
      Start_W_74HC595 = W_74HC595;
    }
    void Plug(Cl_74HC595 *_74HC595) {         // подключить 74HC595 на шине
      _74HC595->pnt = Start_74HC595;
      Start_74HC595 = _74HC595;
    }
};
//--------------------------------------------
//шинa74HC595 Latch=7,CLK=8,Data=12,device=3
Cl_wire_74HC595 Wire(7, 8, 12, 3); // подключить шину на выв 2
Cl_74HC595 _74HC595_U3(&Wire, 1); // подключить шину 74HC595_N1 адр=1
Cl_74HC595 _74HC595_U2(&Wire, 2); // подключить шину 74HC595_N2 адр=2
Cl_74HC595 _74HC595_U1(&Wire, 3); // подключить шину 74HC595_N2 адр=3
Cl_sys Sys;

void setup() {
  Sys.Plug(&Wire);
  Sys.Plug(&_74HC595_U3);
  Sys.Plug(&_74HC595_U2);
  Sys.Plug(&_74HC595_U1);
  Sys.setup();
}
void loop() {
  static uint32_t past = 0;
  static byte a = 0x55;
  if (millis() - past > 300) { //
    _74HC595_U1.write(a = ~a); // здесь организовано переключение
    _74HC595_U2.write(a);      // светодиодов 0.3 вкл + 0.3 выкл
    _74HC595_U3.write(a);      //
  }
  Sys.loop();
}

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

Не хочу показаться назольевым но какойто бардак происходит не понятный. Не одна кнопка не активна просто мегание светодиодов и все

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Alexei39 пишет:

Не хочу показаться назольевым но какойто бардак происходит не понятный. Не одна кнопка не активна просто мегание светодиодов и все

Так последняя программа это и должна делать. Я просто отлавливал в чем я ошибся. И похоже я ее (ошибку) вычислил. Попозже выложу программу целиком.

evgta
Offline
Зарегистрирован: 02.09.2016

Протеус глючный. Шим часто нехочет работать, заливаешь скетч в дуину - работает, в протеус-фиг

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вот написал код . Но управляются кнопками по заданому вами алгоритму только 4 светодиода (1 микросхема в каскаде выв D0,D1,D2,D3)

/*Cl_74HC595_v2.ino

*/
//--------------------class Cl_wire_74HC595------------------------
class Cl_wire_74HC595 {
    byte Latch_pin; // вывод Latch
    byte CLK_pin;   // вывод CLK
    byte Data_pin;  // вывод Data
    byte max_device = 0; // количество 74HC595 в шине
    byte * buffer;// использовать начиная buffer[1],buffer[2],..
  public:
    Cl_wire_74HC595 *pnt = NULL;
    // коструктор
    Cl_wire_74HC595(byte Latch, byte CLK, byte Data, byte device)
      : Latch_pin(Latch), CLK_pin(CLK), Data_pin(Data), max_device(device) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      buffer = new byte[max_device + 1];
      pinMode(Latch_pin, OUTPUT);
      pinMode(CLK_pin, OUTPUT);
      pinMode(Data_pin, OUTPUT);
      for (int i = 0; i > max_device; i++) transferOut(i, 0x00);
    }
    // отправка байта в шину на опред микросх
    //              adr 1,2.  data byte
    void transferOut(byte adr, byte data) {
      if (adr == 0 || adr > max_device)return;
      if (max_device == 0) return;
      buffer[adr] = data;
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device ; j > 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(buffer[j] & (1UL << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // отправка бита в шину на опред вывод опред микросх
    //              adr 1,2,..  _bit 0,1,..  data 0,1
    void transferOut(byte adr, byte _bit, bool data) {
      if (adr == 0 || adr > max_device)return;
      if (_bit > 7)return;
      if (max_device == 0) return;
      (data) ? buffer[adr]  |= (1UL << _bit) : buffer[adr]  &= ~(1UL << _bit);// bitSet :bitClear
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device ; j > 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(buffer[j] & (1UL << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
};
//--------------------class Cl_Led_74HC595------------------------
class Cl_Led_74HC595 {
    Cl_wire_74HC595 *wire;
    byte adr; // адрес микросхемы в шине
    byte pos; // позиция в байте микросхемы
  public:
    Cl_Led_74HC595 *pnt = NULL;
    // конструктор  (шина,позиция в шине 1..5,позиция в байте 0...7)
    Cl_Led_74HC595(Cl_wire_74HC595 *_wire, byte _adr, byte _pos)
      : wire(_wire), adr(_adr), pos(_pos) {}
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      wire->transferOut(adr, pos, LOW);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(byte data) {
      wire->transferOut(adr, pos, data);
    }
    void ON() {
      wire->transferOut(adr, pos, HIGH);
    }
    void OFF() {
      wire->transferOut(adr, pos, LOW);
    }
};
//--------------------class Cl_74HC595------------------------
class Cl_74HC595 {
    Cl_wire_74HC595 *wire;
    byte adr; // адрес микросхемы в шине
  public:
    Cl_74HC595 *pnt = NULL;
    // конструктор  (шина,позиция в шине 1..5)
    Cl_74HC595(Cl_wire_74HC595 *_wire, byte _adr)
      : wire(_wire), adr(_adr) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      wire->transferOut(adr, 0x00);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(byte data) {
      wire->transferOut(adr, data);
    }
};
//----------------class Cl_Btn----------------------------
class Cl_Btn {
    byte pin ; // номер ноги на кнопке
    void (* Do1)(), (* Do2)(), (* Do3)();
    bool btn, btn_old;
    bool bounce_btn = 0; // антидребезговый флаг
    uint32_t past = 0 ;
    uint32_t past1 = 0 ;
    const uint32_t time_1s = 1000 ; // задержка 1 сек
    const uint32_t time_2s = 2000 ; // задержка 2 сек
  public:
    // указатель на следующую
    Cl_Btn *pnt = NULL;
    // конструктор
    Cl_Btn(byte _pin, void (* _Do1)(), void (* _Do2)(), void (* _Do3)())
      : pin(_pin), Do1(_Do1), Do2(_Do2), Do3(_Do3) {};
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      pinMode(pin, INPUT_PULLUP);// подключить кнопку 1 с подтяжкой
      btn = digitalRead(pin); // прочитать реальное значение на выводе};
    }
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
      if (! bounce_btn && btn != digitalRead(pin)) { // если прошел фронт изм на выводн
        bounce_btn = 1;                                 // выставить флаг
        past = millis();                         // сделать временую засветку
      }
      else if ( bounce_btn && millis() - past >= 5 ) { // если прошло антидребезговое время
        bounce_btn = 0;      // то снять флаг
        btn_old = btn ;
        btn = digitalRead(pin) ; // прочитать реальное значение на выводе
        if (btn_old && ! btn)  past1 = millis();
        if (!btn_old && btn) {
          uint32_t time = millis() - past1;
          if (time < time_1s)  Do1();
          else if (time < time_2s)  Do2();
          else Do3();
        }
      }
    }
};
//-----------------class Cl_sys---------------------------
class Cl_sys {
    Cl_wire_74HC595 * Start_W_74HC595   = NULL; // шина 74HC595
    Cl_Led_74HC595  * Start_Led_74HC595 = NULL; // отдельные светодиоды на выводах 74HC595 на шине
    Cl_74HC595      * Start_74HC595     = NULL; // 74HC595 на шине
    Cl_Btn          * Start_Btn         = NULL; // кнопка на выводе
  public:
    Cl_sys() {};
    void setup() {
      Start_W_74HC595   ->setup();
      Start_Led_74HC595 ->setup();
      Start_74HC595     ->setup();
      Start_Btn         ->setup();
    }
    void loop() {
      Start_W_74HC595   ->loop();
      Start_Led_74HC595 ->loop();
      Start_74HC595     ->loop();
      Start_Btn         ->loop();
    }
    void Plug(Cl_wire_74HC595 *obj) { // подключить шину из 74HC595
      obj->pnt  = Start_W_74HC595;
      Start_W_74HC595 = obj;
    }
    void Plug(Cl_Led_74HC595 *obj) { // подключить шину из 74HC595
      obj->pnt  = Start_Led_74HC595;
      Start_Led_74HC595 = obj;
    }
    void Plug(Cl_74HC595 *obj) {     // подключить 74HC595 на шине
      obj->pnt = Start_74HC595;
      Start_74HC595 = obj;
    }
    void Plug(Cl_Btn *obj) {        // подключить кнопку на вывод
      obj->pnt = Start_Btn;
      Start_Btn = obj;
    }
};
//--------------------------------------------
//шинa74HC595 Latch=7,CLK=8,Data=12,device=3
Cl_wire_74HC595 Wire(7, 8, 12, 3); // подключить шину на выв 2

Cl_Led_74HC595 Led_U3_D0(&Wire, 1, 0); // подключить шину 74HC595_N3 адр=1 поз=1
Cl_Led_74HC595 Led_U3_D1(&Wire, 1, 1); // подключить шину 74HC595_N3 адр=1 поз=2
Cl_Led_74HC595 Led_U3_D2(&Wire, 1, 2); // подключить шину 74HC595_N3 адр=1 поз=3
Cl_Led_74HC595 Led_U3_D3(&Wire, 1, 3); // подключить шину 74HC595_N2 адр=1 поз=4

Cl_74HC595 _74HC595_U2(&Wire, 2); // подключить шину 74HC595_N2 адр=2
Cl_74HC595 _74HC595_U1(&Wire, 3); // подключить шину 74HC595_N2 адр=3

void Do1_Btn1() {  // кратковременное нажатие кнопки
  static byte stat = 2;
  if (stat == 2) {
    stat = 0;
    Led_U3_D0.OFF();
    Led_U3_D1.OFF();
  }
  else ++stat;
  if (stat == 1) {
    Led_U3_D0.ON();
    Led_U3_D1.OFF();
  };
  if (stat == 2) {
    Led_U3_D0.OFF();
    Led_U3_D1.ON();
  }
}
void Do2_Btn1() { //  нажатие кнопки 1 сек
  static bool stat = 1;
  stat = !stat;
  if (stat == 0) {
    Led_U3_D2.ON();
  }
  if (stat == 1) {
    Led_U3_D2.OFF();
  }
}
void Do3_Btn1() {  //  нажатие кнопки 2 сек
  static bool stat = 1;
  stat = !stat;
  if (stat == 0) {
    Led_U3_D3.ON();
  }
  if (stat == 1) {
    Led_U3_D3.OFF();
  }
}
// создать кнопку с 3 обработчиками : нажатие < 1сек // 1сек <нажатие<2сек // 2сек <нажатие
Cl_Btn Btn1(6 , Do1_Btn1, Do2_Btn1, Do3_Btn1);// подключить кнопку на выв 6

Cl_sys Sys;

void setup() {
  Sys.Plug(&Wire);
  Sys.Plug(&Led_U3_D0);
  Sys.Plug(&Led_U3_D1);
  Sys.Plug(&Led_U3_D2);
  Sys.Plug(&Led_U3_D3);

  Sys.Plug(&_74HC595_U2);
  Sys.Plug(&_74HC595_U1);

  Sys.Plug(&Btn1);

  Sys.setup();
}
void loop() {

  Sys.loop();
}

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

спасибо большое да заработало. Я только поправел порты выхода на другую микросхему, а скрестить твой и мой код нельзя.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/*Cl_74HC595_v3.ino
*/
//--------------------class Cl_wire_74HC595------------------------
class Cl_wire_74HC595 {
    byte Latch_pin; // вывод Latch
    byte CLK_pin;   // вывод CLK
    byte Data_pin;  // вывод Data
    byte max_device = 0; // количество 74HC595 в шине
    byte * buffer;// использовать начиная buffer[1],buffer[2],..
  public:
    Cl_wire_74HC595 *pnt = NULL;
    // коструктор
    Cl_wire_74HC595(byte Latch, byte CLK, byte Data, byte device)
      : Latch_pin(Latch), CLK_pin(CLK), Data_pin(Data), max_device(device) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      buffer = new byte[max_device + 1];
      pinMode(Latch_pin, OUTPUT);
      pinMode(CLK_pin, OUTPUT);
      pinMode(Data_pin, OUTPUT);
      for (int i = 0; i > max_device; i++) transferOut(i, 0x00);
    }
    // отправка байта в шину на опред микросх
    //              adr 1,2.  data byte
    void transferOut(byte adr, byte data) {
      if (adr == 0 || adr > max_device)return;
      if (max_device == 0) return;
      buffer[adr] = data;
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device ; j > 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(buffer[j] & (1UL << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // отправка бита в шину на опред вывод опред микросх
    //              adr 1,2,..  _bit 0,1,..  data 0,1
    void transferOut(byte adr, byte _bit, bool data) {
      if (adr == 0 || adr > max_device)return;
      if (_bit > 7)return;
      if (max_device == 0) return;
      (data) ? buffer[adr]  |= (1UL << _bit) : buffer[adr]  &= ~(1UL << _bit);// bitSet :bitClear
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device ; j > 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(buffer[j] & (1UL << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
};
//--------------------class Cl_Led_74HC595------------------------
class Cl_Led_74HC595 {
    Cl_wire_74HC595 *wire;
    byte adr; // адрес микросхемы в шине
    byte pos; // позиция в байте микросхемы
  public:
    Cl_Led_74HC595 *pnt = NULL;
    // конструктор  (шина,позиция в шине 1..5,позиция в байте 0...7)
    Cl_Led_74HC595(Cl_wire_74HC595 *_wire, byte _adr, byte _pos)
      : wire(_wire), adr(_adr), pos(_pos) {}
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      wire->transferOut(adr, pos, LOW);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(byte data) {
      wire->transferOut(adr, pos, data);
    }
    void ON() {
      wire->transferOut(adr, pos, HIGH);
    }
    void OFF() {
      wire->transferOut(adr, pos, LOW);
    }
};
//--------------------class Cl_74HC595------------------------
class Cl_74HC595 {
    Cl_wire_74HC595 *wire;
    byte adr; // адрес микросхемы в шине
  public:
    Cl_74HC595 *pnt = NULL;
    // конструктор  (шина,позиция в шине 1..5)
    Cl_74HC595(Cl_wire_74HC595 *_wire, byte _adr)
      : wire(_wire), adr(_adr) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      wire->transferOut(adr, 0x00);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(byte data) {
      wire->transferOut(adr, data);
    }
};
//----------------class Cl_Btn----------------------------
class Cl_Btn {
    byte pin ; // номер ноги на кнопке
    void (* Do1)(), (* Do2)(), (* Do3)();
    bool btn, btn_old;
    bool bounce_btn = 0; // антидребезговый флаг
    uint32_t past = 0 ;
    uint32_t past1 = 0 ;
    const uint32_t time_1s = 1000 ; // задержка 1 сек
    const uint32_t time_2s = 2000 ; // задержка 2 сек
  public:
    // указатель на следующую
    Cl_Btn *pnt = NULL;
    // конструктор
    Cl_Btn(byte _pin, void (* _Do1)(), void (* _Do2)(), void (* _Do3)())
      : pin(_pin), Do1(_Do1), Do2(_Do2), Do3(_Do3) {};
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      pinMode(pin, INPUT_PULLUP);// подключить кнопку 1 с подтяжкой
      btn = digitalRead(pin); // прочитать реальное значение на выводе};
    }
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
      if (! bounce_btn && btn != digitalRead(pin)) { // если прошел фронт изм на выводн
        bounce_btn = 1;                                 // выставить флаг
        past = millis();                         // сделать временую засветку
      }
      else if ( bounce_btn && millis() - past >= 5 ) { // если прошло антидребезговое время
        bounce_btn = 0;      // то снять флаг
        btn_old = btn ;
        btn = digitalRead(pin) ; // прочитать реальное значение на выводе
        if (btn_old && ! btn)  past1 = millis();
        if (!btn_old && btn) {
          uint32_t time = millis() - past1;
          if (time < time_1s)  Do1();
          else if (time < time_2s)  Do2();
          else Do3();
        }
      }
    }
};
//--------------------class Cl_Relay------------------------
class Cl_Relay {
    bool inv; // бит инверсии
    byte pin; // нога Ардуины
  public:
    Cl_Relay *pnt = NULL;
    // конструктор  (нога,бит инверсии)
    Cl_Relay( byte _pin, bool _inv) : pin(_pin), inv(_inv) {}
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      pinMode(pin, OUTPUT);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(bool data) {
      digitalWrite(pin, data ^ inv);
    }
    // включить реле
    void ON() {
      write(1);
    }
    // выключить реле
    void OFF() {
      write(0);
    }
};
//--------------------class Cl_Analog_Sens------------------------
class Cl_Analog_Sens {
    byte pin; // номер ноги на сенсоре
    void (* Do)(); // указатель на обработчик сенсора
  public:
    Cl_Analog_Sens *pnt = NULL;
    int value;// величина на аналоговом датчике
    uint32_t past = 0;
    const uint32_t time = 1000; // опрос датчика идет раз в 1 сек
    Cl_Analog_Sens(byte pin, void (* _Do)()) {}
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      pinMode(pin, OUTPUT);
      value = analogRead(pin);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
      if (millis() - past >= time) {
        past = millis();
        value = analogRead(pin);
      }
    }
};
//-----------------class Cl_sys---------------------------
class Cl_sys {
    Cl_wire_74HC595 * Start_W_74HC595   = NULL; // шина 74HC595
    Cl_Led_74HC595  * Start_Led_74HC595 = NULL; // отдельные светодиоды на выводах 74HC595 на шине
    Cl_74HC595      * Start_74HC595     = NULL; // 74HC595 на шине
    Cl_Btn          * Start_Btn         = NULL; // кнопка на выводе
    Cl_Relay        * Start_Relay       = NULL; // реле на выводе
    Cl_Analog_Sens  * Start_An_Sens     = NULL; // аналоговый сенсор с обработчиком
  public:
    Cl_sys() {};
    void setup() {
      Start_W_74HC595   ->setup();
      Start_Led_74HC595 ->setup();
      Start_74HC595     ->setup();
      Start_Btn         ->setup();
      Start_Relay       ->setup();
      Start_An_Sens     ->setup();
    }
    void loop() {
      Start_W_74HC595   ->loop();
      Start_Led_74HC595 ->loop();
      Start_74HC595     ->loop();
      Start_Btn         ->loop();
      Start_Relay       ->loop();
      Start_An_Sens     ->loop();
    }
    void Plug(Cl_wire_74HC595 *obj) { // подключить шину из 74HC595
      obj->pnt  = Start_W_74HC595;
      Start_W_74HC595 = obj;
    }
    void Plug(Cl_Led_74HC595 *obj) { // подключить шину из 74HC595
      obj->pnt  = Start_Led_74HC595;
      Start_Led_74HC595 = obj;
    }
    void Plug(Cl_74HC595 *obj) {     // подключить 74HC595 на шине
      obj->pnt = Start_74HC595;
      Start_74HC595 = obj;
    }
    void Plug(Cl_Btn *obj) {        // подключить кнопку на вывод
      obj->pnt = Start_Btn;
      Start_Btn = obj;
    }
    void Plug(Cl_Relay *obj) {        // подключить реле на выход
      obj->pnt = Start_Relay;
      Start_Relay = obj;
    }
    void Plug(Cl_Analog_Sens *obj) {  // подключить аналоговый сенсор с обработчиком
      obj->pnt = Start_An_Sens;
      Start_An_Sens = obj;
    }
};
//--------------------------------------------
//шинa74HC595 Latch=7,CLK=8,Data=12,device=3
Cl_wire_74HC595 Wire(7, 8, 12, 3); // подключить шину на выв 2

Cl_Led_74HC595 Led_U3_D0(&Wire, 1, 0); // подключить шину 74HC595_N3 адр=1 поз=1
Cl_Led_74HC595 Led_U3_D1(&Wire, 1, 1); // подключить шину 74HC595_N3 адр=1 поз=2
Cl_Led_74HC595 Led_U3_D2(&Wire, 1, 2); // подключить шину 74HC595_N3 адр=1 поз=3
Cl_Led_74HC595 Led_U3_D3(&Wire, 1, 3); // подключить шину 74HC595_N2 адр=1 поз=4

Cl_74HC595 _74HC595_U2(&Wire, 2); // подключить шину 74HC595_N2 адр=2
Cl_74HC595 _74HC595_U1(&Wire, 3); // подключить шину 74HC595_N2 адр=3

void Do1_Btn1() {  // кратковременное нажатие кнопки
  static byte stat = 2;
  if (stat == 2) {
    stat = 0;
    Led_U3_D0.OFF();
    Led_U3_D1.OFF();
  }
  else ++stat;
  if (stat == 1) {
    Led_U3_D0.ON();
    Led_U3_D1.OFF();
  }
  if (stat == 2) {
    Led_U3_D0.OFF();
    Led_U3_D1.ON();
  }
}
void Do2_Btn1() { //  нажатие кнопки 1 сек
  static bool stat = 1;
  stat = !stat;
  if (stat == 0) {
    Led_U3_D2.ON();
  }
  if (stat == 1) {
    Led_U3_D2.OFF();
  }
}
void Do3_Btn1() {  //  нажатие кнопки 2 сек
  static bool stat = 1;
  stat = !stat;
  if (stat == 0) {
    Led_U3_D3.ON();
  }
  if (stat == 1) {
    Led_U3_D3.OFF();
  }
}
// создать кнопку с 3 обработчиками : нажатие < 1сек // 1сек <нажатие<2сек // 2сек <нажатие
Cl_Btn Btn1(6 , Do1_Btn1, Do2_Btn1, Do3_Btn1);// подключить кнопку на выв 6

// создать реле на выходе
Cl_Relay  Relay_in_Home (17, 0); // salon
Cl_Relay  Relay_out_Home(16, 0); // ulica
Cl_Relay  Relay_Hot     (15, 0); // gor
Cl_Relay  Relay_Cold    (14, 0); // xol

void Do_Water_Sens();
Cl_Analog_Sens Water_Sens(A7, Do_Water_Sens); // подключить аналоговый сенсор на выв A7

const byte Viev_map[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
void Do_Water_Sens() {
  const int level_water = 512;
  Relay_Cold.OFF();
  Relay_Hot.OFF();
  if (Water_Sens.value < level_water)Relay_Cold.ON();
  if (Water_Sens.value > level_water)Relay_Hot.ON();
  _74HC595_U2.write(Viev_map[Water_Sens.value / 8] );
}

void Do_Air_Sens();
Cl_Analog_Sens Air_Sens(A6, Do_Air_Sens); // подключить аналоговый сенсор на выв A7

void Do_Air_Sens() {
  const int level_air = 512;
  Relay_out_Home.OFF();
  Relay_in_Home.OFF();
  if (Air_Sens.value > level_air)Relay_out_Home.ON();
  if (Air_Sens.value < level_air)Relay_in_Home.ON();
  _74HC595_U1.write(Viev_map[Air_Sens.value / 8] );
}

Cl_sys Sys;

void setup() {
  Sys.Plug(&Wire);
  Sys.Plug(&Led_U3_D0);
  Sys.Plug(&Led_U3_D1);
  Sys.Plug(&Led_U3_D2);
  Sys.Plug(&Led_U3_D3);

  Sys.Plug(&_74HC595_U2);
  Sys.Plug(&_74HC595_U1);

  Sys.Plug(&Btn1);

  Sys.Plug(&Relay_in_Home );
  Sys.Plug(&Relay_out_Home);
  Sys.Plug(&Relay_Hot     );
  Sys.Plug(&Relay_Cold    );

  Sys.Plug(&Water_Sens    );
  Sys.Plug(&Air_Sens      );

  Sys.setup();
}
void loop() {

  Sys.loop();
}

Скрестить код можно, но у вас навыков нет, а мне не имеет смысла.  У меня же готовый конструктор по типа Лего. Собирай чего хочешь.

Alexei39
Offline
Зарегистрирован: 26.03.2016

А где можно почитать про эти конструкторы

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Alexei39 пишет:

А где можно почитать про эти конструкторы

http://variable.saraff.ru/page.php?pg=19

/*Cl_74HC595_v3.ino
  шина 74HC595 из соединеных каскадом <-- 7,8,12 (Latch,CLK,Data) 3 штуки
  74HC595_U1                          <-- шина 74HC595 (адр 3)
  74HC595_U2                          <-- шина 74HC595 (адр 2)

  Led_U3_D0                           <-- шина 74HC595 (адр 1,поз 0)
  Led_U3_D1                           <-- шина 74HC595 (адр 1,поз 1)
  Led_U3_D2                           <-- шина 74HC595 (адр 1,поз 2)
  Led_U3_D3                           <-- шина 74HC595 (адр 1,поз 3)

  кнопка  Btn1                        <-- 6 ардуино

  реле Relay_in_Home                  -->17 ардуино // salon
  реле Relay_out_Home                 -->16 ардуино // ulica
  реле Relay_Hot                      -->15  ардуино// gor
  реле Relay_Cold                     -->14 ардуино // xol

  аналог сенсор  Air_Sens             <-- A6 ардуино
  аналог сенсор  Water_Sens           <-- A7 ардуино
*/
//--------------------- настройки пользователя --------------------
const int level_water = 512 ;// порог переключения водяного сенсора
const int level_air   = 512 ;// порог переключения воздушного сенсора
//--------------------class Cl_wire_74HC595------------------------
// класс шины из каскадного соединения нескольких 74HC595
class Cl_wire_74HC595 {
    byte Latch_pin; // вывод Latch
    byte CLK_pin;   // вывод CLK
    byte Data_pin;  // вывод Data
    byte max_device = 0; // количество 74HC595 в шине
    byte * buffer;// использовать начиная buffer[1],buffer[2],..
  public:
    Cl_wire_74HC595 *pnt = NULL;
    // коструктор
    Cl_wire_74HC595(byte Latch, byte CLK, byte Data, byte device)
      : Latch_pin(Latch), CLK_pin(CLK), Data_pin(Data), max_device(device) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      buffer = new byte[max_device + 1];
      pinMode(Latch_pin, OUTPUT);
      pinMode(CLK_pin, OUTPUT);
      pinMode(Data_pin, OUTPUT);
      for (int i = 0; i > max_device; i++) transferOut(i, 0x00);
    }
    // отправка байта в шину на опред микросх
    //              adr 1,2.  data byte
    void transferOut(byte adr, byte data) {
      if (adr == 0 || adr > max_device)return;
      if (max_device == 0) return;
      buffer[adr] = data;
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device ; j > 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(buffer[j] & (1UL << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // отправка бита в шину на опред вывод опред микросх
    //              adr 1,2,..  _bit 0,1,..  data 0,1
    void transferOut(byte adr, byte _bit, bool data) {
      if (adr == 0 || adr > max_device)return;
      if (_bit > 7)return;
      if (max_device == 0) return;
      (data) ? buffer[adr]  |= (1UL << _bit) : buffer[adr]  &= ~(1UL << _bit);// bitSet :bitClear
      digitalWrite(Latch_pin, LOW);
      for (int j = max_device ; j > 0; j-- ) {
        for (int i = 7; i >= 0; i--) {
          digitalWrite(Data_pin, !!(buffer[j] & (1UL << i)));
          digitalWrite(CLK_pin, HIGH);
          digitalWrite(CLK_pin, LOW);
        }
      }
      digitalWrite(Latch_pin, HIGH);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
};
//--------------------class Cl_Led_74HC595------------------------
// класс светодиода на выводе одной из 74HC595 соединенных каскадом
class Cl_Led_74HC595 {
    Cl_wire_74HC595 *wire;
    byte adr; // адрес микросхемы в шине
    byte pos; // позиция в байте микросхемы
  public:
    Cl_Led_74HC595 *pnt = NULL;
    // конструктор  (шина,позиция в шине 1..5,позиция в байте 0...7)
    Cl_Led_74HC595(Cl_wire_74HC595 *_wire, byte _adr, byte _pos)
      : wire(_wire), adr(_adr), pos(_pos) {}
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      wire->transferOut(adr, pos, LOW);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(byte data) {
      wire->transferOut(adr, pos, data);
    }
    void ON() {
      wire->transferOut(adr, pos, HIGH);
    }
    void OFF() {
      wire->transferOut(adr, pos, LOW);
    }
};
//--------------------class Cl_74HC595------------------------
// класс  одной из 74HC595 соединенных каскадом
class Cl_74HC595 {
    Cl_wire_74HC595 *wire;
    byte adr; // адрес микросхемы в шине
  public:
    Cl_74HC595 *pnt = NULL;
    // конструктор  (шина,позиция в шине 1..5)
    Cl_74HC595(Cl_wire_74HC595 *_wire, byte _adr)
      : wire(_wire), adr(_adr) {};
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      wire->transferOut(adr, 0x00);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(byte data) {
      wire->transferOut(adr, data);
    }
};
//----------------class Cl_Btn_3----------------------------
// класс кнопки с 3 обработкиками : короткое нажатие(меньше 1 сек),среднее нажатие(1-2 сек),длиное нажатие(больше 2 сек)
class Cl_Btn_3 {
    byte pin ; // номер ноги на кнопке
    void (* Do1)(), (* Do2)(), (* Do3)();
    bool btn, btn_old;
    bool bounce_btn = 0; // антидребезговый флаг
    uint32_t past = 0 ;
    uint32_t past1 = 0 ;
    const uint32_t time_1s = 1000 ; // задержка 1 сек
    const uint32_t time_2s = 2000 ; // задержка 2 сек
  public:
    // указатель на следующую
    Cl_Btn_3 *pnt = NULL;
    // конструктор
    Cl_Btn_3(byte _pin, void (* _Do1)(), void (* _Do2)(), void (* _Do3)())
      : pin(_pin), Do1(_Do1), Do2(_Do2), Do3(_Do3) {};
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      pinMode(pin, INPUT_PULLUP);// подключить кнопку 1 с подтяжкой
      btn = digitalRead(pin); // прочитать реальное значение на выводе};
    }
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
      if (! bounce_btn && btn != digitalRead(pin)) { // если прошел фронт изм на выводн
        bounce_btn = 1;                                 // выставить флаг
        past = millis();                         // сделать временую засветку
      }
      else if ( bounce_btn && millis() - past >= 5 ) { // если прошло антидребезговое время
        bounce_btn = 0;      // то снять флаг
        btn_old = btn ;
        btn = digitalRead(pin) ; // прочитать реальное значение на выводе
        if (btn_old && ! btn)  past1 = millis();
        if (!btn_old && btn) {
          uint32_t time = millis() - past1;
          if (time < time_1s)  Do1();
          else if (time < time_2s)  Do2();
          else Do3();
        }
      }
    }
};
//--------------------class Cl_Relay------------------------
// класс реле подключеных нв вывод ардуины
class Cl_Relay {
    bool inv; // бит инверсии
    byte pin; // нога Ардуины
  public:
    Cl_Relay *pnt = NULL;
    // конструктор  (нога,бит инверсии)
    Cl_Relay( byte _pin, bool _inv) : pin(_pin), inv(_inv) {}
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      pinMode(pin, OUTPUT);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
    }
    // запись байта
    void write(bool data) {
      digitalWrite(pin, data ^ inv);
    }
    // включить реле
    void ON() {
      write(1);
    }
    // выключить реле
    void OFF() {
      write(0);
    }
};
//--------------------class Cl_Analog_Sens------------------------
// класс аналогового сенсора повешанного на аналогов вывод Ардуины
// с обработчиком вызываемых каждую секунду
class Cl_Analog_Sens {
    byte pin; // номер ноги на сенсоре
    void (* Do)(); // указатель на обработчик сенсора
  public:
    Cl_Analog_Sens *pnt = NULL;
    int value;// величина на аналоговом датчике
    uint32_t past = 0;
    const uint32_t time = 1000; // опрос датчика идет раз в 1 сек
    Cl_Analog_Sens(byte pin, void (* _Do)()) {}
    // setup()
    void setup() {
      if (this->pnt != NULL) this->pnt->setup();
      pinMode(pin, OUTPUT);
      value = analogRead(pin);
    }
    // loop()
    void loop() {
      if (this->pnt != NULL) this->pnt->loop();
      if (millis() - past >= time) {
        past = millis();
        value = analogRead(pin);
      }
    }
};
//-----------------class Cl_sys---------------------------
// класс собирающий объекты разных классов в единую систему
class Cl_sys {
    Cl_wire_74HC595 * Start_W_74HC595   = NULL; // шина 74HC595
    Cl_Led_74HC595  * Start_Led_74HC595 = NULL; // отдельные светодиоды на выводах 74HC595 на шине
    Cl_74HC595      * Start_74HC595     = NULL; // 74HC595 на шине
    Cl_Btn_3        * Start_Btn_3       = NULL; // кнопка на выводе
    Cl_Relay        * Start_Relay       = NULL; // реле на выводе
    Cl_Analog_Sens  * Start_An_Sens     = NULL; // аналоговый сенсор с обработчиком
  public:
    Cl_sys() {};
    void setup() {
      Start_W_74HC595   ->setup();
      Start_Led_74HC595 ->setup();
      Start_74HC595     ->setup();
      Start_Btn_3       ->setup();
      Start_Relay       ->setup();
      Start_An_Sens     ->setup();
    }
    void loop() {
      Start_W_74HC595   ->loop();
      Start_Led_74HC595 ->loop();
      Start_74HC595     ->loop();
      Start_Btn_3       ->loop();
      Start_Relay       ->loop();
      Start_An_Sens     ->loop();
    }
    void Plug(Cl_wire_74HC595 *obj) { // подключить шину из 74HC595
      obj->pnt  = Start_W_74HC595;
      Start_W_74HC595 = obj;
    }
    void Plug(Cl_Led_74HC595 *obj) { // подключить шину из 74HC595
      obj->pnt  = Start_Led_74HC595;
      Start_Led_74HC595 = obj;
    }
    void Plug(Cl_74HC595 *obj) {     // подключить 74HC595 на шине
      obj->pnt = Start_74HC595;
      Start_74HC595 = obj;
    }
    void Plug(Cl_Btn_3 *obj) {        // подключить кнопку на вывод
      obj->pnt = Start_Btn_3;
      Start_Btn_3 = obj;
    }
    void Plug(Cl_Relay *obj) {        // подключить реле на выход
      obj->pnt = Start_Relay;
      Start_Relay = obj;
    }
    void Plug(Cl_Analog_Sens *obj) {  // подключить аналоговый сенсор с обработчиком
      obj->pnt = Start_An_Sens;
      Start_An_Sens = obj;
    }
};
//--------------------------------------------
//  раздел для создания объектов по классам

//шинa74HC595 Latch=7,CLK=8,Data=12,device=3
Cl_wire_74HC595 Wire(7, 8, 12, 3); // подключить шину на выв 2

Cl_Led_74HC595 Led_U3_D0(&Wire, 1, 0); // подключить шину 74HC595_N3 адр=1 поз=1
Cl_Led_74HC595 Led_U3_D1(&Wire, 1, 1); // подключить шину 74HC595_N3 адр=1 поз=2
Cl_Led_74HC595 Led_U3_D2(&Wire, 1, 2); // подключить шину 74HC595_N3 адр=1 поз=3
Cl_Led_74HC595 Led_U3_D3(&Wire, 1, 3); // подключить шину 74HC595_N2 адр=1 поз=4

Cl_74HC595 _74HC595_U2(&Wire, 2); // подключить шину 74HC595_N2 адр=2
Cl_74HC595 _74HC595_U1(&Wire, 3); // подключить шину 74HC595_N2 адр=3

void Do1_Btn1() {  // кратковременное нажатие кнопки
  static byte stat = 2;
  if (stat == 2) {
    stat = 0;
    Led_U3_D0.OFF();
    Led_U3_D1.OFF();
  }
  else ++stat;
  if (stat == 1) {
    Led_U3_D0.ON();
    Led_U3_D1.OFF();
  }
  if (stat == 2) {
    Led_U3_D0.OFF();
    Led_U3_D1.ON();
  }
}
void Do2_Btn1() { //  нажатие кнопки 1 сек
  static bool stat = 1;
  stat = !stat;
  if (stat == 0) {
    Led_U3_D2.ON();
  }
  if (stat == 1) {
    Led_U3_D2.OFF();
  }
}
void Do3_Btn1() {  //  нажатие кнопки 2 сек
  static bool stat = 1;
  stat = !stat;
  if (stat == 0) {
    Led_U3_D3.ON();
  }
  if (stat == 1) {
    Led_U3_D3.OFF();
  }
}
// создать кнопку с 3 обработчиками : нажатие < 1сек // 1сек <нажатие<2сек // 2сек <нажатие
Cl_Btn_3    Btn1(6, Do1_Btn1, Do2_Btn1, Do3_Btn1);// подключить кнопку на выв 6

// создать реле на выходе
Cl_Relay  Relay_in_Home (17, 0); // salon
Cl_Relay  Relay_out_Home(16, 0); // ulica
Cl_Relay  Relay_Hot     (15, 0); // gor
Cl_Relay  Relay_Cold    (14, 0); // xol

void Do_Water_Sens();
Cl_Analog_Sens Water_Sens(A7, Do_Water_Sens); // подключить аналоговый сенсор на выв A7

const byte Viev_map[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
void Do_Water_Sens() {
  Relay_Cold.OFF();
  Relay_Hot.OFF();
  if (Water_Sens.value < level_water)Relay_Cold.ON();
  if (Water_Sens.value > level_water)Relay_Hot.ON();
  _74HC595_U2.write(Viev_map[Water_Sens.value / 8] );
}

void Do_Air_Sens();
Cl_Analog_Sens Air_Sens(A6, Do_Air_Sens); // подключить аналоговый сенсор на выв A7

void Do_Air_Sens() {
  Relay_out_Home.OFF();
  Relay_in_Home.OFF();
  if (Air_Sens.value > level_air)Relay_out_Home.ON();
  if (Air_Sens.value < level_air)Relay_in_Home.ON();
  _74HC595_U1.write(Viev_map[Air_Sens.value / 8] );
}

Cl_sys Sys;

void setup() {
  //-раздел для функций подключения элементов
  Sys.Plug(&Wire);
  Sys.Plug(&Led_U3_D0);
  Sys.Plug(&Led_U3_D1);
  Sys.Plug(&Led_U3_D2);
  Sys.Plug(&Led_U3_D3);

  Sys.Plug(&_74HC595_U2);
  Sys.Plug(&_74HC595_U1);

  Sys.Plug(&Btn1);

  Sys.Plug(&Relay_in_Home );
  Sys.Plug(&Relay_out_Home);
  Sys.Plug(&Relay_Hot     );
  Sys.Plug(&Relay_Cold    );

  Sys.Plug(&Water_Sens    );
  Sys.Plug(&Air_Sens      );

  Sys.setup();
}
void loop() {

  Sys.loop();
}

 

Alexei39
Offline
Зарегистрирован: 26.03.2016

Спасибо. Постораюсь вникнуть. Если тебя не затруднит дошии код под всю схему.

Зарание огромное спасибо.

Просто пока лето хочеться закончить эпопею с печкой.