SX1509 — 16-канальный GPIO-интерфейс (Arduino)

Модуль SX1509 — это 16-канальный GPIO-интерфейс с расширенными функциями, выпущенный компанией Semtech. Модуль имеет двухстороннюю связь с микроконтроллером, что обеспечивает высокую скорость передачи данных, а также позволяет использовать функции микроконтроллера для управления I/O-модулем.

Кроме 16 доступных для подключения каналов, модуль имеет встроенный светодиодный драйвер и поддерживает подключение клавиатуры (до 64 ключей).

Модуль SX1509 имеет широкий диапазон напряжений питания от 1,2 В до 3,6 В, что позволяет использовать его с большинством микроконтроллеров и устройств. Встроенные функции программирования позволяют настраивать каждый канал, чтобы он мог выполнять различные действия, такие как включение/выключение светодиодов, установка ШИМ на выходах, чтение состояний входных сигналов и так далее.

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

По умолчанию используется I2C адрес 0x3E.

При выборе режима работы не все GPIO поддерживаю выбранный режим работы, используйте таблицу для выбора необходимого GPIO I/O.

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

Read/Write GPIO

Ниже показан демонстрационный скетч, который демонстрирует работу чтения и записи GPIO входа/выхода. Для демонстрации работы скетча Вам необходимо подключить светодиод к выходу 15 (через сопротивление 100 Ом) и кнопку (нажатие — замыкание на GND) ко входу 0.

При нажатии на кнопку светодиод будет загораться и гаснуть при повторном нажатии на кнопку.

#include <Wire.h>          
#include <SparkFunSX1509.h> // http://librarymanager/All#SparkFun_SX1509

const byte SX1509_ADDRESS = 0x3E; //  I2C address
SX1509 io;                       

const byte SX1509_LED_PIN = 15; // LED pin 15 
const byte SX1509_BUTTON_PIN = 0; // Button pin 0 

bool ledState = false;

void setup(){
  Serial.begin(9600);
  Wire.begin(); 
  pinMode(13, OUTPUT); 
  digitalWrite(13, LOW);
  if (io.begin(SX1509_ADDRESS) == false){Serial.println("I2C ERROR");
  digitalWrite(13, HIGH); while(1);}

  io.pinMode(SX1509_LED_PIN, OUTPUT);
  io.pinMode(SX1509_BUTTON_PIN, INPUT_PULLUP);
}

void loop(){
  if (io.digitalRead(SX1509_BUTTON_PIN) == LOW){
    Serial.print("BUTTON_PIN status: ");
    Serial.println(io.digitalRead(SX1509_BUTTON_PIN));

    ledState = !ledState;
    io.digitalWrite(SX1509_LED_PIN, ledState);

    Serial.print("LED_PIN status: ");
    Serial.println(ledState);

    Serial.print("Waiting for button to release...");
    while (io.digitalRead(SX1509_BUTTON_PIN) == LOW); 
    Serial.println("Button released!");

    delay(200);
  }
}

PWM GPIO

Каждый выход GPIO может работать как PWM выход с разрешением 8 бит. Следующий скетч демонстрирует работу PWM. К выходу 15 GPIO подключен светодиод (через сопротивление 100 Ом), после загрузки скетча он будет плавно загораться и гаснуть.

#include <Wire.h>          
#include <SparkFunSX1509.h> // http://librarymanager/All#SparkFun_SX1509

const byte SX1509_ADDRESS = 0x3E; //  I2C address
SX1509 io;                       

const byte SX1509_LED_PIN = 15; // LED pin 15 

bool ledState = false;

void setup(){
  Serial.begin(9600);
  Wire.begin(); 
  pinMode(13, OUTPUT); 
  digitalWrite(13, LOW);
  if (io.begin(SX1509_ADDRESS) == false){Serial.println("I2C ERROR");
  digitalWrite(13, HIGH); while(1);}

  io.pinMode(SX1509_LED_PIN, ANALOG_OUTPUT);
}

void loop(){
 for (int brightness = 0; brightness < 256; brightness++){
    io.analogWrite(SX1509_LED_PIN, brightness);
    delay(2); 
  }
  delay(500); 

  for (int brightness = 255; brightness >= 0; brightness--){
    io.analogWrite(SX1509_LED_PIN, brightness);
    delay(2); 
  }
  delay(500);
}

OSC OUTPUT

SX1509 имеет внутренний генератор с частотой 2 МГц, за счет деления этой частоты на выходе OSC можно получить меандр, частота которой рассчитывается по формуле:

Fpin_osc = Fosc/2^(outputFreq-1)

Следует отметить то, что внутренний генератор SX1509 имеет весьма большую погрешность.

#include <Wire.h>          
#include <SparkFunSX1509.h> // http://librarymanager/All#SparkFun_SX1509

const byte SX1509_ADDRESS = 0x3E; //  I2C address
SX1509 io;                       

// PIN OSC OUTPUT

bool ledState = false;

void setup(){
  Serial.begin(9600);
  Wire.begin(); 
  pinMode(13, OUTPUT); 
  digitalWrite(13, LOW);
  if (io.begin(SX1509_ADDRESS) == false){Serial.println("I2C ERROR");
  digitalWrite(13, HIGH); while(1);}
  
  byte outputFreq = 4; 
  io.clock(INTERNAL_CLOCK_2MHZ, 2, OUTPUT, outputFreq);
  //Fpin_osc = Fosc/2^(outputFreq-1)
  //Fpin_osc = 2 000 000 / 2^3 = 2 000 000 / 8 = 250 000 Hz
}

void loop(){}

digitalReadInterrupt

В модуле SX1509 имеется выход Interrupt (INT) для вывода сигнала прерывания. В данном примере при нажатии кнопку которая подключена ко входу GPIO 0, происходит прерывание, на выходе INT появляется сигнал прерывания.

io.enableInterrupt(SX1509_BUTTON_PIN, FALLING);

Сигнал прерывания подается на вход D2 платы Arduino. Arduino так же настроено на работу с прерыванием.

attachInterrupt(digitalPinToInterrupt(ARDUINO_INT_PIN),button, FALLING);

attachInterrupt задает функцию обработки внешнего прерывания, то есть функция, которая будет вызвана по внешнему прерыванию.

При появлении сигнала прерывания на D2, происходит прерывание, исполняется функция button() которая устанавливает флаг прерывания buttonPressed в true.

Так как флаг buttonPressed true, в цикле loop() исполняется код который выводит состояние флага buttonPressed и меняет его на false, что блокирует повторное исполнение кода до следующего нажатии кнопки.

#include <Wire.h>          
#include <SparkFunSX1509.h> // http://librarymanager/All#SparkFun_SX1509

const byte SX1509_ADDRESS = 0x3E; //  I2C address
SX1509 io;                       

const byte SX1509_BUTTON_PIN = 0; // IO 0 connected to button

// Arduino Pins (not SX1509!)
const byte ARDUINO_INT_PIN = 2; // SX1509 int output to D2
bool buttonPressed = false; // Track button press in ISR

void setup(){
  Serial.begin(9600);
  Wire.begin(); 
  pinMode(13, OUTPUT); 
  digitalWrite(13, LOW);
  if (io.begin(SX1509_ADDRESS) == false){Serial.println("I2C ERROR");
  digitalWrite(13, HIGH); while(1);}
  
   io.pinMode(SX1509_BUTTON_PIN, INPUT_PULLUP);
   io.enableInterrupt(SX1509_BUTTON_PIN, FALLING);
  //  0, 1, 2, 4, 8, 16, 32, or 64 ms.
  io.debounceTime(32); 
  io.debouncePin(SX1509_BUTTON_PIN); 
  pinMode(ARDUINO_INT_PIN, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(ARDUINO_INT_PIN),button, FALLING);
}

void loop(){
  if (buttonPressed){
   
    unsigned int intStatus = io.interruptSource();
    Serial.println("intStatus = " + String(intStatus, BIN));
 
    if (intStatus & (1 << SX1509_BUTTON_PIN)){
      Serial.println("Button pressed!"); 
    }

    buttonPressed = false; 
  }
}

void button(){buttonPressed = true; }

Дополнительно в скетче используется функции io.debounceTime() и io.debouncePin() позволяющие устранить дребезг нажатия кнопки. В io.debounceTime() указывается время задержки после нажатия кнопки, а io.debouncePin() указывается номер GPIO который используется для кнопки.

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

Добавить комментарий

Войти с помощью: