модернизация библиотеки или кто как читает 74HC165)
- Войдите на сайт для отправки комментариев
Здравствуйте, появилась необходимость расширить пины на 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);
}
может быть я заблуждаюсь совсем, по неопытности в программировании, подскажите лучший вариант опроса регистров)
т.к. готовая конструкция и SPI занят
Чем занят? Когда освободится? Можно ли занимать очередь? Или больше 2 в одни руки не дают?
А если ему сообщение оставить и он попоже перезвонит?
т.к. готовая конструкция и SPI занят
Чем занят? Когда освободится? Можно ли занимать очередь? Или больше 2 в одни руки не дают?
А если ему сообщение оставить и он попоже перезвонит?
только программно) это минус проэкта...
тоесть микросхему припаять вы можете а в 3 проводка к SPI выводам подпаять у вас рука не подымается?
это не страшно.. раз паяльничком и все.. как укол
вот вам для примера
тоесть микросхему припаять вы можете а в 3 проводка к SPI выводам подпаять у вас рука не подымается?
именно так) так схема УЖЕ заточена и SPI иногда включается и отключается.
именно так) так схема УЖЕ заточена и SPI иногда включается и отключается.
сам? чип работает а SPI хочет включилось хочет выключилось?
класс! вы из обычных деталей реализовали атмегу размером с комнату?
именно так) так схема УЖЕ заточена и SPI иногда включается и отключается.
сам? чип работает а SPI хочет включилось хочет выключилось?
класс! вы из обычных деталей реализовали атмегу размером с комнату?
Puhlyaviy может по сути? я помощи просил а не что бы мне двойки ставили)
а не что бы мне двойки ставили)
Так никто-никгода не просит двоек ставить. А ставить нужно :)
Я бы примерно так делал:
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(); }; #endifAH_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(){ }Гарантирую только компилируемость. Проверить - у меня неначем. Но "идея", думаю понятна.
отлично всё работает спасибо за код) у меня ком порт не работает по наболевшей причине и не как прочитать на компе, благо есть 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]); } }Наверное было-бы не плохо, как-то переименовать эти файлы/класс во что-то типа AH_74HC165_MULTIPLE или что-то такое.
Что-бы не создавать "библиотечный ад", когда по сети гуляет фигова туча версий/разных библиотек с одинаковым именем и фиг разберешься какая правильная, какую нужно использовать с этим примером и т.п. С enc28j60, с экранами, с SD и т.п. уже есть такая проблема. Не хотелось бы быть зачинателем еще одной :)
так и сделал AH_74HC165_UPDATE, вобще я давно искал что то подобное, думаю не только я один)
так и сделал AH_74HC165_UPDATE, вобще я давно искал что то подобное, думаю не только я один)
Update - плохой префикс. Ничего не говорит (вообщем-то даже вводит в заблуждение, типа библиотека еще что-то и апдейтит). Да вообще именование библиотек типа SomeName, SameNameNew, SameNameVeryNew и т.п. - IMHO вредное. Счас она NEW/UPDATED, а через год... уже не такая уж она и новая :)
Так что MULTIPLE, MULTI, Several, Few - было бы более предпочтительно.
Или вообще не привызявать имя к функционалу. Просто что-то уникальное. Не обазательно даже что-бы значило что-то. BramboReader, Skyfly, Hrumpotopatam какой-нибудь :)
Но это уже "так....". На ваш выбор. Просто мои размышления. Можете и AH_74HC165_UPDATE оставить. Возможно имеет смысл не только файлы переименовать, но и само имя класса тоже сменить.
full shift ~SPI )))))))))))))))) здесь фантазий может быть много))) я нашёл оригинал здесь http://arduino-projekte.de/ очень не плохой ресурс для начинающих и не только.
поделитесь пожалуйста измененной библиотекой. тоже понадобится считывать с нескольких регистров
прочитайте всю тему и поймёте)
ребята помогите справиться.
Взял последнюю модернизированную библиотеку. Странно работает. То правильно читатает, то только младших 4 бита.
Все входящие линии притянуты к питанию резисторами по 10кОм. 11111110 - это правильно считанное состояние регистра. Я на макетке уже все провода шевелил, и микросхему менял, ничего не помогает. На ардуино Нано напряжение проседает до 4,6В скорее всего из-за слабого кабеля. Регистр запитан от ардуины, соответственно то-же 4,6 В. Это может повлиять?
Вот прочитанное из регистра:
#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. Все то-же самое
вопрос решился подачей стабильных 5В прямо на контроллер
Как правильно каскад собирать под эту библиотеку? Так?
Схема каскада описана в даташите и от библиотеки вообще не зависит
Перепаял схему. Второй каскад заработал, но выдает:
1000000000
100000000
10000000
1000000
100000
10000
1000
100
10
1
Все подключил как указано в даташите. По битам выводит в монитор, но какието сбои, помехи. Регистра два, использую 10 входов. Может не нужные заземлить, а используемые подтянуть резисторами к нулю?
Может быть, а может и не к нулю. Схема то где ? Ненужные биты вы можете просто игнорировать или вам обязательно красивую картинку в мониторе порта надо ?
Может быть, а может и не к нулю. Схема то где ? Ненужные биты вы можете просто игнорировать или вам обязательно красивую картинку в мониторе порта надо ?
Как я могу использовать эти данные со сбоями в коде для выполнения чего либо, через раз срабатывать будет.
К примеру: if (intValue == 1111110000000001) {motor_s1();}
Если нужно именно двоичное число. А так, как у вас - оно десятичное, да еще и 256-битное ))
К примеру: if (intValue == 1111110000000001) {motor_s1();}
зачем такую глупость писать? Я у вас уже спрашивал, как определить. число двоичное или десятичное? Вот в этой строчке выше - вы же никак не обьяснили компилятору, что это двоичное число! Поэтому он будет с ним обращаться, как с десятичным - то есть считать это 111 триллионов 111 миллиардов один.
И вообще, это совсем не так делается. Почитайте что-нить про битовые операции