модернизация библиотеки или кто как читает 74HC165)

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

Здравствуйте,  появилась необходимость расширить пины на 64 кнопки, решил сделать на 74hc165, в инете много разных мудрёных кодов видел но готового и простого решения не нашёл, по SPI, shiftin() не подходит т.к. готовая конструкция и SPI занят(  приходится городить программно, нашёл библиотеку AH_74HC165 вродибы всё просто но  нет возможности нарастить микрухи, есть вариант сделать эту либу именно под мой проект например в самой либе вместо 8 бит указать long и будет 32 бита, но этого всё равно мало, хотелось бы сделать универсальной её что бы можно было указывать в константах или переменных количество микрух, привожу код;

AH_74HC165.h

#ifndef AH_74HC165_h
#define AH_74HC165_h

#include <Arduino.h>   //Arduino IDE >= V1.0


class AH_74HC165
{
  public:
    // Constructor
    AH_74HC165(int Q7, int PL, int CLOCK, int CE);   		

   	byte Read();


  private:
	int  _DATA_Pin;
  	int  _LOAD_Pin;
  	int  _CLOCK_Pin;
  	int  _CLOCK_ENABLE_Pin;

        void Clock();
   	void Load();
};

#endif 

AH_74HC165.cpp

#include <Arduino.h>
#include <AH_74HC165.h>

//************
// Constructor
AH_74HC165::AH_74HC165(int Q7, int PL, int CLOCK, int CE){	

	_DATA_Pin  = Q7;
	_LOAD_Pin  = PL;
	_CLOCK_Pin = CLOCK;
	_CLOCK_ENABLE_Pin = CE;
	
	pinMode(_DATA_Pin, INPUT);

	pinMode(_LOAD_Pin, OUTPUT);
        digitalWrite(_LOAD_Pin, HIGH);

	pinMode(_CLOCK_Pin, OUTPUT);
        digitalWrite(_CLOCK_Pin, LOW);

	pinMode(_CLOCK_ENABLE_Pin, OUTPUT);
        digitalWrite(_CLOCK_ENABLE_Pin, HIGH);

}

//************

void AH_74HC165::Clock(){

  digitalWrite(_CLOCK_Pin, HIGH); 
  digitalWrite(_CLOCK_Pin, LOW);   

} 

//************
void AH_74HC165::Load(){

  digitalWrite(_LOAD_Pin, LOW); 
  digitalWrite(_LOAD_Pin, HIGH);

} 

//************

byte AH_74HC165::Read(){

  Load();

  byte data = 0;

  digitalWrite(_CLOCK_ENABLE_Pin, LOW);

  for (int i=0; i<8;i++){
    data |= digitalRead(_DATA_Pin)<<(7-i); 
    Clock();
  }

  digitalWrite(_CLOCK_ENABLE_Pin, HIGH);
  
  return data;
} 

AH_74HC165.ino

#include <AH_74HC165.h>

//AH_74HC165(int Q7, int PL, int CLOCK, int CE); 
AH_74HC165 ic165(6,5,4,3);

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

void loop() {
    Serial.println(ic165.Read(),BIN);
    Serial.println(ic165.Read()); 
    Serial.println();   
    delay(1000);
}

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

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

radiofannat пишет:

 т.к. готовая конструкция и SPI занят

Чем занят? Когда освободится?  Можно ли занимать очередь? Или больше 2 в одни руки не дают?

А если ему сообщение оставить и он попоже перезвонит?

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

Puhlyaviy пишет:

radiofannat пишет:

 т.к. готовая конструкция и SPI занят

Чем занят? Когда освободится?  Можно ли занимать очередь? Или больше 2 в одни руки не дают?

А если ему сообщение оставить и он попоже перезвонит?

только программно) это минус проэкта...

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

тоесть микросхему припаять вы можете а в 3 проводка к SPI выводам подпаять у вас рука не подымается?

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

это не страшно.. раз паяльничком и все.. как укол

вот вам для примера

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

Puhlyaviy пишет:

тоесть микросхему припаять вы можете а в 3 проводка к SPI выводам подпаять у вас рука не подымается?

именно так) так схема УЖЕ заточена и SPI иногда включается и отключается.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

radiofannat пишет:

именно так) так схема УЖЕ заточена и SPI иногда включается и отключается.

сам? чип работает а SPI хочет включилось хочет выключилось?

класс! вы из обычных деталей реализовали атмегу размером с комнату?

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

Puhlyaviy пишет:

radiofannat пишет:

именно так) так схема УЖЕ заточена и SPI иногда включается и отключается.

сам? чип работает а SPI хочет включилось хочет выключилось?

класс! вы из обычных деталей реализовали атмегу размером с комнату?

Puhlyaviy может по сути? я помощи просил а не что бы мне двойки ставили)

leshak
Offline
Зарегистрирован: 29.09.2011

radiofannat пишет:

 а не что бы мне двойки ставили)

Так никто-никгода не просит двоек ставить. А ставить нужно :)

Я бы примерно так делал:

AH_74HC165.h 

#ifndef AH_74HC165_h
#define AH_74HC165_h

#include <Arduino.h>   //Arduino IDE >= V1.0



class AH_74HC165
{
  public:
    // Constructor
    AH_74HC165(int Q7, int PL, int CLOCK, int CE);   		

   	byte Read();
    void ReadBytes(byte* buff,byte byteCount);// buff - куда будем читать, byteCount - сколько байт прочитать нужно


  private:
	int  _DATA_Pin;
  	int  _LOAD_Pin;
  	int  _CLOCK_Pin;
  	int  _CLOCK_ENABLE_Pin;

    void Clock();
   	void Load();

    byte Load8Bits();
};

#endif 

AH_74HC165.cpp

#include <Arduino.h>
#include <AH_74HC165.h>

//************
// Constructor
AH_74HC165::AH_74HC165(int Q7, int PL, int CLOCK, int CE){	

	_DATA_Pin  = Q7;
	_LOAD_Pin  = PL;
	_CLOCK_Pin = CLOCK;
	_CLOCK_ENABLE_Pin = CE;
	
	pinMode(_DATA_Pin, INPUT);

	pinMode(_LOAD_Pin, OUTPUT);
        digitalWrite(_LOAD_Pin, HIGH);

	pinMode(_CLOCK_Pin, OUTPUT);
        digitalWrite(_CLOCK_Pin, LOW);

	pinMode(_CLOCK_ENABLE_Pin, OUTPUT);
        digitalWrite(_CLOCK_ENABLE_Pin, HIGH);

}

//************

void AH_74HC165::Clock(){

  digitalWrite(_CLOCK_Pin, HIGH); 
  digitalWrite(_CLOCK_Pin, LOW);   

} 

//************
void AH_74HC165::Load(){

  digitalWrite(_LOAD_Pin, LOW); 
  digitalWrite(_LOAD_Pin, HIGH);

} 

//************

byte AH_74HC165::Read(){

  
  byte data = 0;
  ReadBytes(&data,sizeof(byte));

  return data;
} 


void AH_74HC165::ReadBytes(byte* buff,byte byteCount){
  Load();

  

  digitalWrite(_CLOCK_ENABLE_Pin, LOW);

   for(byte bt=0;bt<byteCount;bt++){
      *(buff+bt)=Load8Bits();
   }

   

  digitalWrite(_CLOCK_ENABLE_Pin, HIGH);
  
  
}


//************

byte AH_74HC165::Load8Bits(){
  byte data = 0;
  for (int i=0; i<8;i++){
    data |= digitalRead(_DATA_Pin)<<(7-i); 
    Clock();
  }

  return data;

}

 

Sample:

#include <AH_74HC165.h>

AH_74HC165 hc(10,11,12,13); // номера пинов от балды поставил

void setup(){
  
 byte value= hc.Read(); // чтение одной микрухи
 Serial.println(value,BIN);
 
 unsigned int intValue;
 
 hc.ReadBytes((byte*)&intValue,sizeof(int)); // чтение двух микрух
 Serial.println(intValue,BIN);
 
 byte byteArr[15];
 hc.ReadBytes(byteArr,15);// чтение 15-ти микрух
 
 for(byte i=0;i<15;i++){
   Serial.print("Byte");Serial.print(i);
   Serial.print("=");Serial.println(byteArr[i],BIN);
 }
 
 
 
}

void loop(){
}

Гарантирую только компилируемость. Проверить - у меня неначем. Но "идея", думаю понятна. 

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

отлично всё работает спасибо за код) у меня ком порт не работает по наболевшей причине и не как прочитать на компе, благо есть max7219, вот так и читал каждую кнопку)))

#include <AH_74HC165.h>
AH_74HC165 hc(42,41,43,34);

#include "LedControl.h"
LedControl lc=LedControl(29,31,33,2);

void setup(){
  int devices=lc.getDeviceCount();
  for(int address=0;address<devices;address++) {
  lc.shutdown(address,false);
  lc.setIntensity(address,0);
  lc.clearDisplay(address);
  }
}

void loop(){
   byte byteArr[8];
   hc.ReadBytes(byteArr,8);// чтение 8-ми микрух
   for(byte i=0;i<8;i++){
   lc.setRow(0,i,~byteArr[i]);
 }
}
leshak
Offline
Зарегистрирован: 29.09.2011

Наверное было-бы не плохо, как-то переименовать эти файлы/класс во что-то типа AH_74HC165_MULTIPLE или что-то такое.

Что-бы не создавать "библиотечный ад", когда по сети гуляет фигова туча версий/разных библиотек с одинаковым именем и фиг разберешься какая правильная, какую нужно использовать с этим примером и т.п. С enc28j60, с экранами, с SD и т.п. уже есть такая проблема. Не хотелось бы быть зачинателем еще одной :)

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

так и сделал AH_74HC165_UPDATE, вобще я давно искал что то подобное, думаю не только я один)

leshak
Offline
Зарегистрирован: 29.09.2011

radiofannat пишет:

так и сделал AH_74HC165_UPDATE, вобще я давно искал что то подобное, думаю не только я один)

Update - плохой префикс. Ничего не говорит (вообщем-то даже вводит в заблуждение, типа библиотека еще что-то и апдейтит). Да вообще именование библиотек типа SomeName, SameNameNew, SameNameVeryNew и т.п. - IMHO вредное. Счас она NEW/UPDATED, а через год... уже не такая уж она и новая :)

Так что MULTIPLE, MULTI, Several, Few - было бы более предпочтительно.

Или вообще не привызявать имя к функционалу. Просто что-то уникальное. Не обазательно даже что-бы значило что-то. BramboReader, Skyfly, Hrumpotopatam какой-нибудь :)

Но это уже "так....". На ваш выбор. Просто мои размышления. Можете и AH_74HC165_UPDATE оставить. Возможно имеет смысл не только файлы переименовать, но и само имя класса тоже сменить.

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

full shift ~SPI ))))))))))))))))   здесь фантазий может быть много))) я нашёл оригинал здесь http://arduino-projekte.de/ очень не плохой ресурс для начинающих и не только.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

 

radiofannat
radiofannat аватар
Offline
Зарегистрирован: 11.09.2013

прочитайте всю тему и поймёте)

RainMan
Offline
Зарегистрирован: 21.06.2011

ребята помогите справиться.

Взял последнюю модернизированную библиотеку. Странно работает. То правильно читатает, то только младших 4 бита. 

Все входящие линии притянуты к питанию резисторами по 10кОм. 11111110 - это правильно считанное состояние регистра. Я на макетке уже все провода шевелил, и микросхему менял, ничего не помогает. На ардуино Нано напряжение проседает до 4,6В скорее всего из-за слабого кабеля. Регистр запитан от ардуины, соответственно то-же 4,6 В. Это может повлиять?

Вот прочитанное из регистра:

1110
1110
11111110
11111110
11111110
11111110
1110
1110
1110
1110
1110
1110
1110
1110
1110
1110
11111110
11111110
 
Вот скетч:
#include <AH_74HC165.h>
//AH_74HC165(int Q7 , int PL , int CLOCK , int CE );
// Распиновка на регистре
//  _DATA_Pin  = Q7(9 pin); (подлключать к MISO если SPI)
//  _LOAD_Pin  = PL(1 pin);
//  _CLOCK_Pin = CLOCK (2 pin); ( подключать к SCK если SPI)
//  _CLOCK_ENABLE_Pin = CE (15 pin);

AH_74HC165 hc(9,10,11,12); // номера пинов 
byte value;

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

void loop(){
  value = hc.Read(); // чтение одной микрухи
  Serial.println(value,BIN);
  delay(500);
}

Пробовал работать с регистром через SPI. Все то-же самое

 

RainMan
Offline
Зарегистрирован: 21.06.2011

вопрос решился подачей стабильных 5В прямо на контроллер

Duet
Offline
Зарегистрирован: 17.01.2015

Как правильно каскад собирать под эту библиотеку? Так?

b707
Offline
Зарегистрирован: 26.05.2017

Схема каскада описана в даташите и от библиотеки вообще не зависит

Duet
Offline
Зарегистрирован: 17.01.2015

Перепаял схему. Второй каскад заработал, но выдает:

1000000000

100000000

10000000

1000000

100000

10000

1000

100

10

1

Duet
Offline
Зарегистрирован: 17.01.2015

Все подключил как указано в даташите. По битам выводит в монитор, но какието сбои, помехи. Регистра два, использую 10 входов. Может не нужные заземлить, а используемые подтянуть резисторами к нулю?

Morroc
Offline
Зарегистрирован: 24.10.2016

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

Duet
Offline
Зарегистрирован: 17.01.2015

Morroc пишет:

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

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

К примеру: if (intValue == 1111110000000001) {motor_s1();}

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020
if (intValue == Bx1111110000000001)

Если нужно именно двоичное число. А так, как у вас - оно десятичное, да еще и 256-битное ))

b707
Offline
Зарегистрирован: 26.05.2017

Duet пишет:

К примеру: if (intValue == 1111110000000001) {motor_s1();}

зачем такую глупость писать? Я у вас уже спрашивал, как определить. число двоичное или десятичное? Вот в этой строчке выше - вы же никак не обьяснили компилятору, что это двоичное число! Поэтому он будет с ним обращаться, как с десятичным - то есть считать это 111 триллионов 111 миллиардов один.

И вообще, это совсем не так делается. Почитайте что-нить про битовые операции