Read с PCF8574 с использованием attachInterrupt
- Войдите на сайт для отправки комментариев
Ср, 02/08/2017 - 22:10
Здравствуйте.
Используя функцию attachInterrupt хочу считать данные с PCF8574
Функция void read() не работает если эти строки присутствуют
int x = pcf20.read8();
Serial.print("Read ");
Serial.println(x, HEX);
Может это только в протеусе так?
#include <PCF8574.h>
#include <Wire.h>
PCF8574 pcf20(0x20);
void setup() {
pcf20.begin();
Serial.begin(9600);
attachInterrupt(0, read,FALLING);
Serial.println("Start");
pcf20.write(4, LOW);
pcf20.write(5, LOW);
pcf20.write(6, LOW);
pcf20.write(7, LOW);
}
void loop() {
///
}
void read()
{
Serial.println("Read");
int x = pcf20.read8();
Serial.print("Read ");
Serial.println(x, HEX);
}

Честно, в лом смотреть как устроена pcf20.read8, но попробуйте после строки 21 вставить sei(); и отпишитесь заработало ли.
Заработало.
Этим sei(); остановили прерывания?
Разрешили прерывания.
Спасибо.
Подскажите, прерывания мешают выполнению основного цикла, как это исправить?
#include <iarduino_I2C_IO_Global.h> int timer,timerPrev=0; boolean status = false; void setup() { Serial.begin(9600); Serial.println("Start"); iarduino_I2C_IO_Global.begin(); attachInterrupt(0, read,FALLING); pinMode(uint16_t(0), OUTPUT);//0 пин микросхемы PCF8574 с адресом 0x20 pinMode(uint16_t(1), OUTPUT);//1 пин микросхемы PCF8574 с адресом 0x20 pinMode(uint16_t(2), OUTPUT); pinMode(uint16_t(3), OUTPUT); pinMode(uint16_t(4), INPUT ); pinMode(uint16_t(5), INPUT ); pinMode(uint16_t(6), INPUT ); pinMode(uint16_t(7), INPUT ); digitalWrite(uint16_t(0), LOW); digitalWrite(uint16_t(1), LOW); digitalWrite(uint16_t(2), LOW); digitalWrite(uint16_t(3), LOW); } void loop(){ timer = millis(); if (timer-timerPrev>1000){ status=!status; digitalWrite(uint16_t(0), status); timerPrev=timer; } } void read() { sei(); Serial.println(digitalRead(uint16_t(4))); }Я не понимаю, что значит "прерывания мешают выполнению основного цикла"? Как именно мешают? С чего Вы взяли, что они мешают?
И ещё, не стоит использовать
Serial.printlnв обрботчике прерывания. для отладки там глянут ещё так-сяк, но серьёзно использовать не стоит. Уберите.Serial.printlnв обрботчике прерывания использую для отладки, в протеусе, для наглядности.digitalWrite(uint16_t(0), status); перестаёт "мигать" если срабатывает attachInterrupt(0, read,FALLING);
https://youtu.be/NDRSUBPvDOE
Это не связано с прерываниями. У Вас типы данных для времени неправильный Исправляйте. Не поможет, будем дальше смотреть.
Евгений, тип поменял,но что-то тут....на видео понятно будет.
https://youtu.be/c1wwi1T1i2Q
На выходе INT PCF8574 0 и пусто?
#include <iarduino_I2C_IO_Global.h> unsigned long timer,timerPrev=0; boolean status = false; void setup() { Serial.begin(9600); Serial.println("Start"); iarduino_I2C_IO_Global.begin(); attachInterrupt(0, read,CHANGE); pinMode(uint16_t(0), OUTPUT); pinMode(uint16_t(1), OUTPUT); pinMode(uint16_t(2), OUTPUT); pinMode(uint16_t(3), OUTPUT); pinMode(uint16_t(4), INPUT ); pinMode(uint16_t(5), INPUT ); pinMode(uint16_t(6), INPUT ); pinMode(uint16_t(7), INPUT ); digitalWrite(uint16_t(0), LOW); digitalWrite(uint16_t(1), LOW); digitalWrite(uint16_t(2), LOW); digitalWrite(uint16_t(3), LOW); } void loop(){ timer = millis(); if (timer-timerPrev>1000){ status=!status; digitalWrite(uint16_t(0), status); timerPrev=timer; } } void read() { sei(); digitalWrite(uint16_t(1), digitalRead(uint16_t(4))); }Разобрался, с библиотекой <PCF8574.h> всё работает
Вас не смущает, что Вы в строках 32 и 40 пишете в пины 0 и 1, а на них же у Вас сидит Serial, который Вы инициализировали?
uint16_t(0) это 0 нога микросхемы PCF8274 с адресолм 0x20
Ну, Вам виднее.
https://lesson.iarduino.ru/page/rasshiritel-na-8-vhodov-vyhodov-trema-mo...
Прочитайте статью внимательней, в последнем фрагменте коде явно какая-то ерунда написана.
Ну, Вам виднее.
Женя. Это правда. Та библиотека перегружает стандартные digitalRead() и digitalWrite().
Для меня - плохо, но кому-то понравится. Я вообще перегрузки не люблю... Это "не честный С" ;) ;) ;)
#ifndef __IARDUINO_I2C_IO_GLOBAL_H__ #define __IARDUINO_I2C_IO_GLOBAL_H__ #include <iarduino_I2C_IO.h> iarduino_I2C_IO iarduino_I2C_IO_Global; void pinMode (uint16_t i, uint8_t j) { iarduino_I2C_IO_Global.pinMode (i,j);} bool digitalRead (uint16_t i) {return iarduino_I2C_IO_Global.digitalRead (i );} void digitalWrite (uint16_t i, uint8_t j) { iarduino_I2C_IO_Global.digitalWrite (i,j);} #endif<PCF8574.h> мне понравилась больше
<PCF8574.h> мне понравилась больше
Женя. Это правда. Та библиотека перегружает стандартные digitalRead() и digitalWrite().
Так я и не спорил. Я не знаю той библиотеки, потому и сказал, что ТС виднее.
Ещё вопрос, нужно ли подтянуть INT пин микросхемы PCF к +5?
Если не притянут к +5, то на выходе INT Proteus кажет вопросительный знак, почему?
Если притянуть к +5 через 10кОм, то кажет 1.
При этом Ардуино считывает прерывания. Вот видео что происходит:
https://youtu.be/FqQTqywV4G8
В даташите написано, что выход INT - открытый сток, а это значит ему нужно подтягивающее сопротивление в плюс.
Поэтому в шпроте и чередуется 0 с высокоимпедансным состоянием (подключено в никуда)
Сделано это для возможности объединения практически неограниченного количества таких мс на одно прерывание, методом монтажного И
Спасибо
Наткнулась на видео, заинтересовало считывание и запись без использования библиотек.
https://www.youtube.com/watch?v=QnmePPzPFYc (со 2 минуты)
Там такой код:
#include <Wire.h> #define adres 0x20 #define adres1 0x21 void setup() { Wire.begin(); Wire.beginTransmission(adres); Wire.write(0b00000001); Wire.write(0b00000000); Wire.endTransmission(); } void loop() { }Для чего отсылать два байта? (с одним байтом всё работает)
Потому что видео про 8575, а не про 8574. У первой в два раза больше I/O портов.
Вот это невнимательность.....Спасибочки. (надо закупаться 8575, количество адресов такое же, а портов в два раза больше)
#include <Wire.h> #define adres 0x20 #define adres1 0x21 void setup() { Serial.begin(9600); Wire.begin(); Serial.println("Start"); } void loop() { Wire.requestFrom(adres1,7); if (Wire.available()){ Wire.beginTransmission(adres); Wire.write(Wire.read()); Wire.endTransmission(); } }Я верно считываю с одной микросхемы и записываю в другую? 7 байт нужно считывать?
Больше ног - легче запутаться в них. Да и разводить сложнее.
Еще есть мнение, что MCP23017 получше на выход работает.
Почему 6 , а не 7? Ножек же по 8 (16)
Больше ног - легче запутаться в них. Да и разводить сложнее.
Еще есть мнение, что MCP23017 получше на выход работает.
Стоят дешевле. Надо попробовать.
Почему 6 , а не 7? Ножек же по 8 (16)
Потомушто нечего по ютубу учиться программированию. Прокомментировать действия видеоблоггера я не могу.
И зачем вам с одной PCF писать в другую 7 байт?
Одна ардуина будет собирать данные от 80-100 кнопок и передавать на расстояние (либо по радиоканалу, либо RS-485) другой ардуино, которая будет выводить светодиодами состояние кнопок.
И что, все эти кнопки у вас на одной PCF-ке? Вы понимаете, что с 8574, например, можно только один байт читать? Если у Вас семь раз спросить Ваше имя, то Вы назовете семь разных?
Вот это невнимательность.....Спасибочки. (надо закупаться 8575, количество адресов такое же, а портов в два раза больше)
Поаккуратней с 8575, которые мне на Али попадались, тянут только вниз, нету верхнего плеча.
P/S Да и корпус гнусненький.((((
Понимаю.
#include <Wire.h> #define adres 0x20 #define adres1 0x21 #define adres2 0x22 #define adres3 0x23 void setup() { Serial.begin(9600); Wire.begin(); /*Wire.beginTransmission(adres2); Wire.beginTransmission(0b11111111); Wire.beginTransmission(0b11111111); Wire.write(Wire.read());*/ Serial.println("Start"); } void loop() { Wire.requestFrom(adres1,7); if (Wire.available()){ Wire.beginTransmission(adres); Wire.write(Wire.read()); Wire.endTransmission(); } Wire.requestFrom(adres2,7); if (Wire.available()){ Wire.beginTransmission(adres3); Wire.write(Wire.read()); Wire.endTransmission(); } } Соответственно в цикле считывать буду.Если понимаете, то нарисуйте алгоритм. Я пока что не вижу его из кода. Вижу, что вы вместо семи бит пытаетесь семь байт получить.
#include <Wire.h> byte Input[]={0x21,0x22}; byte Output[]={0x20,0x23}; unsigned long Times; void setup() { Serial.begin(9600); Wire.begin(); Serial.println("Start"); } void loop() { if (millis()-Times>=500){ Times=millis(); Serial.println("Status"); for (byte i=0; i<=2; i++){ Wire.requestFrom(Input[i],7); if (Wire.available()){ Wire.beginTransmission(Output[i]); Wire.write(Wire.read()); Wire.endTransmission(); } } } } как-то такВот это невнимательность.....Спасибочки. (надо закупаться 8575, количество адресов такое же, а портов в два раза больше)
Поаккуратней с 8575, которые мне на Али попадались, тянут только вниз, нету верхнего плеча.
P/S Да и корпус гнусненький.((((
А мне что низ, что верх, разницы никакой.
Больше ног - легче запутаться в них. Да и разводить сложнее.
Еще есть мнение, что MCP23017 получше на выход работает.
Полностью доверюсь мнению sadman41 и буду использовать их.
А мне что низ, что верх, разницы никакой.
Типа, на всякий случай.))) У меня транзисторы npn должны были открывать, всю плату переделывать пришлось.)))
Последний раз спрошу - зачем 7 байт читаете с однобайтовой PCF-ки?
Последний раз спрошу - зачем 7 байт читаете с однобайтовой PCF-ки?
Wire.requestFrom(Input[i],1);
Всё всё всё...Поняла))))
В MCP23017 уже записываем 2 байта?
#include <Wire.h> void setup() { Wire.begin(); Wire.beginTransmission(0x20); Wire.write("0b11111111"); Wire.write("0b11111111"); Wire.endTransmission(); } void loop() { }И, тогда, лучше через байтовую переменную обменивайте. Так, хотя бы, не запутаетесь что у кого забрали и кому отдали.
И, тогда, лучше через байтовую переменную обменивайте. Так, хотя бы, не запутаетесь что у кого забрали и кому отдали.
Ну да, так и буду, при реализации передачи, скорее всего через RS-485
Что-то неправильно я сделала
#include <Wire.h> void setup() { Wire.begin(); Wire.beginTransmission(0x20); Wire.write("0b11111111"); Wire.write("0b11111111"); Wire.endTransmission(); } void loop() { }Что-то неправильно я сделала
Интуиция вас не подводит. А вот пальцы подводят - засылают в МС строки вместо байт.
В 23017 все через использование конретных регистров производится. Если автоинкремент не включен.
#include<Wire.h> void setup(){ Wire.begin(); //Порт А-все выходы Wire.beginTransmission(0x20); Wire.write(0x00); Wire.write(0x00); Wire.endTransmission(); //Порт B-все выходы Wire.beginTransmission(0x20); Wire.write(0x01); Wire.write(0x00); Wire.endTransmission(); //Порт А-все 1 Wire.beginTransmission(0x20); Wire.write(0x12); Wire.write(0xFF); Wire.endTransmission(); //Порт B-все 1 Wire.beginTransmission(0x20); Wire.write(0x13); Wire.write(0xFF); Wire.endTransmission(); } void loop(){ }Запись получилась. Чтение на день оставлю. Спасибо. Доброй ночи.
100 кнопок, это не клавиатура, случаем?
Если да, то проще обычную PS/2 подключить.
Нее. Не она)
теперь всю ночь не спать буду, варочаца, думать, кудыж в Ардуине 100 кнопок надо.
На ёлке лампочки зажигать.