Das wäre naheliegend, nur finde ich in der Bibliothek Adafruit_IS31FL3731 keine Stelle, wo die Farbe aufgedröselt wird. Siehst Du mehr?
Das sehe ich auch so.
Das IC IS31FL3731 steuert eine Matrix einzelner LEDs an. Der Schaltplan zeigt, daß beispielsweise CA9, CA3 und CA4 in einem RGB-Gehäuse mit Anode an CA1 zusammengefaßt sind. Lt. Datenblatt sind das die PWM-Register A4h, 44h und 54h.
Zieht man den Offset 24h für die PWM-Register ab, erhält man die Werte 80h=128, 20h=32 und 30h=48, die sich auch in einer Python-Tabelle wiederfinden. Könnte also möglicherweise passen.
Die Methode void Adafruit_IS31FL3731_5x5RGB::drawPixel(uint8_t a, uint8_t b, uint8_t c) bezieht sich jetzt nur auf genau diese drei LEDs, deren Helligkeit eingestellt wird. Das Testprogramm macht die einzelnen LEDs nacheinander an, dann alle aus. Idealerweise sollten sich die LEDs innerhalb eines RGB-Gehäuses befinden.
Testprogramm
// 5x5 LED Matrix
// Bibliotheken
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_IS31FL3731.h>
Adafruit_IS31FL3731_5x5RGB matrix = Adafruit_IS31FL3731_5x5RGB();
// ##########--- SETUP ---##########
void setup()
{
//
Serial.begin(115200);
if (!matrix.begin(0x74))
{
Serial.println("IS31 nicht gefunden");
while (1);
}
Serial.println("IS31 gefunden!");
}
// ##########--- LOOP ---##########
void loop()
{
matrix.clear();
matrix.drawPixel(255, 0, 0); // Farbe a
delay(2000);
matrix.drawPixel(0, 255, 0); // Farbe b
delay(2000);
matrix.drawPixel(0, 0, 255); // Farbe c
delay(2000);
matrix.drawPixel(0, 0, 0); // aus
delay(2000);
}
Adafruit_IS31FL3731.h
#ifndef _ADAFRUIT_IS31FL3731_H_
#define _ADAFRUIT_IS31FL3731_H_
#include <Adafruit_GFX.h>
#include <Adafruit_I2CDevice.h>
#include <Arduino.h>
#define ISSI_ADDR_DEFAULT 0x74
#define ISSI_REG_CONFIG 0x00
#define ISSI_REG_CONFIG_PICTUREMODE 0x00
#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08
#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18
#define ISSI_CONF_PICTUREMODE 0x00
#define ISSI_CONF_AUTOFRAMEMODE 0x04
#define ISSI_CONF_AUDIOMODE 0x08
#define ISSI_REG_PICTUREFRAME 0x01
#define ISSI_REG_SHUTDOWN 0x0A
#define ISSI_REG_AUDIOSYNC 0x06
#define ISSI_COMMANDREGISTER 0xFD
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
/**************************************************************************/
/*!
@brief Constructor for generic IS31FL3731 breakout version
*/
/**************************************************************************/
class Adafruit_IS31FL3731 : public Adafruit_GFX {
public:
Adafruit_IS31FL3731(uint8_t x = 16, uint8_t y = 9);
bool begin(uint8_t addr = ISSI_ADDR_DEFAULT, TwoWire *theWire = &Wire);
void drawPixel(int16_t x, int16_t y, uint16_t color);
void clear(void);
void setLEDPWM(uint8_t lednum, uint8_t pwm, uint8_t bank = 0);
void audioSync(bool sync);
void setFrame(uint8_t b);
void displayFrame(uint8_t frame);
protected:
bool selectBank(uint8_t bank);
bool writeRegister8(uint8_t bank, uint8_t reg, uint8_t data);
uint8_t readRegister8(uint8_t bank, uint8_t reg);
uint8_t _frame; ///< The frame (of 8) we are currently addressing
private:
Adafruit_I2CDevice *_i2c_dev = NULL;
};
/**************************************************************************/
/*!
@brief Constructor for FeatherWing IS31FL3731 version
*/
/**************************************************************************/
class Adafruit_IS31FL3731_Wing : public Adafruit_IS31FL3731 {
public:
Adafruit_IS31FL3731_Wing(void);
void drawPixel(int16_t x, int16_t y, uint16_t color);
};
/**************************************************************************/
/*!
@brief Constructor for 5x5RGB version
*/
/**************************************************************************/
class Adafruit_IS31FL3731_5x5RGB : public Adafruit_IS31FL3731 {
public:
Adafruit_IS31FL3731_5x5RGB(void);
void drawPixel(uint8_t a, uint8_t b, uint8_t c);
};
#endif
Adafruit_IS31FL3731.cpp
#include <Adafruit_IS31FL3731.h>
#ifndef _swap_int16_t
#define _swap_int16_t(a, b) \
{ \
int16_t t = a; \
a = b; \
b = t; \
}
#endif
/**************************************************************************/
/*!
@brief Constructor for breakout version
@param width Desired width of led display
@param height Desired height of led display
*/
/**************************************************************************/
Adafruit_IS31FL3731::Adafruit_IS31FL3731(uint8_t width, uint8_t height)
: Adafruit_GFX(width, height) {}
/**************************************************************************/
/*!
@brief Constructor for FeatherWing version (15x7 LEDs)
*/
/**************************************************************************/
Adafruit_IS31FL3731_Wing::Adafruit_IS31FL3731_Wing(void)
: Adafruit_IS31FL3731(15, 7) {}
/**************************************************************************/
/*!
@brief Constructor for 5x5RGB version (5x5 LEDs)
*/
/**************************************************************************/
Adafruit_IS31FL3731_5x5RGB::Adafruit_IS31FL3731_5x5RGB(void)
: Adafruit_IS31FL3731(5, 5) {}
/**************************************************************************/
/*!
@brief Initialize hardware and clear display
@param addr The I2C address we expect to find the chip at
@param theWire The TwoWire I2C bus device to use, defaults to &Wire
@returns True on success, false if chip isnt found
*/
/**************************************************************************/
bool Adafruit_IS31FL3731::begin(uint8_t addr, TwoWire *theWire) {
if (_i2c_dev) {
delete _i2c_dev;
}
_i2c_dev = new Adafruit_I2CDevice(addr, theWire);
if (!_i2c_dev->begin()) {
return false;
}
_i2c_dev->setSpeed(400000);
_frame = 0;
// shutdown
writeRegister8(ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x00);
delay(10);
// out of shutdown
writeRegister8(ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x01);
// picture mode
writeRegister8(ISSI_BANK_FUNCTIONREG, ISSI_REG_CONFIG,
ISSI_REG_CONFIG_PICTUREMODE);
displayFrame(_frame);
// all LEDs on & 0 PWM
clear(); // set each led to 0 PWM
for (uint8_t f = 0; f < 8; f++) {
for (uint8_t i = 0; i <= 0x11; i++)
writeRegister8(f, i, 0xff); // each 8 LEDs on
}
audioSync(false);
return true;
}
/**************************************************************************/
/*!
@brief Sets all LEDs on & 0 PWM for current frame.
*/
/**************************************************************************/
void Adafruit_IS31FL3731::clear(void) {
selectBank(_frame);
uint8_t erasebuf[25];
memset(erasebuf, 0, 25);
for (uint8_t i = 0; i < 6; i++) {
erasebuf[0] = 0x24 + i * 24;
_i2c_dev->write(erasebuf, 25);
}
}
/**************************************************************************/
/*!
@brief Low level accesssor - sets a 8-bit PWM pixel value to a bank location
does not handle rotation, x/y or any rearrangements!
@param lednum The offset into the bank that corresponds to the LED
@param bank The bank/frame we will set the data in
@param pwm brightnes, from 0 (off) to 255 (max on)
*/
/**************************************************************************/
void Adafruit_IS31FL3731::setLEDPWM(uint8_t lednum, uint8_t pwm, uint8_t bank) {
if (lednum >= 144)
return;
writeRegister8(bank, 0x24 + lednum, pwm);
}
/**************************************************************************/
/*!
@brief Adafruit GFX low level accesssor - sets a 8-bit PWM pixel value
handles rotation and pixel arrangement, unlike setLEDPWM
@param x The x position, starting with 0 for left-most side
@param y The y position, starting with 0 for top-most side
@param color Despite being a 16-bit value, takes 0 (off) to 255 (max on)
*/
/**************************************************************************/
void Adafruit_IS31FL3731_Wing::drawPixel(int16_t x, int16_t y, uint16_t color) {
// check rotation, move pixel around if necessary
switch (getRotation()) {
case 1:
_swap_int16_t(x, y);
x = 15 - x - 1;
break;
case 2:
x = 15 - x - 1;
y = 7 - y - 1;
break;
case 3:
_swap_int16_t(x, y);
y = 9 - y - 1;
break;
}
// charlie wing is smaller:
if ((x < 0) || (x >= 16) || (y < 0) || (y >= 7))
return;
if (x > 7) {
x = 15 - x;
y += 8;
} else {
y = 7 - y;
}
_swap_int16_t(x, y);
if (color > 255)
color = 255; // PWM 8bit max
setLEDPWM(x + y * 16, color, _frame);
return;
}
/**************************************************************************/
/*!
*/
/**************************************************************************/
void Adafruit_IS31FL3731_5x5RGB::drawPixel(uint8_t a, uint8_t b, uint8_t c)
{
setLEDPWM(0xA4, a, _frame);
setLEDPWM(0x44, b, _frame);
setLEDPWM(0x54, c, _frame);
return;
}
/**************************************************************************/
/*!
@brief Adafruit GFX low level accesssor - sets a 8-bit PWM pixel value
handles rotation and pixel arrangement, unlike setLEDPWM
@param x The x position, starting with 0 for left-most side
@param y The y position, starting with 0 for top-most side
@param color Despite being a 16-bit value, takes 0 (off) to 255 (max on)
*/
/**************************************************************************/
void Adafruit_IS31FL3731::drawPixel(int16_t x, int16_t y, uint16_t color) {
// check rotation, move pixel around if necessary
switch (getRotation()) {
case 1:
_swap_int16_t(x, y);
x = 16 - x - 1;
break;
case 2:
x = 16 - x - 1;
y = 9 - y - 1;
break;
case 3:
_swap_int16_t(x, y);
y = 9 - y - 1;
break;
}
if ((x < 0) || (x >= 16))
return;
if ((y < 0) || (y >= 9))
return;
if (color > 255)
color = 255; // PWM 8bit max
setLEDPWM(x + y * 16, color, _frame);
return;
}
/**************************************************************************/
/*!
@brief Set's this object's frame tracker (does not talk to the chip)
@param frame Ranges from 0 - 7 for the 8 frames
*/
/**************************************************************************/
void Adafruit_IS31FL3731::setFrame(uint8_t frame) { _frame = frame; }
/**************************************************************************/
/*!
@brief Have the chip set the display to the contents of a frame
@param frame Ranges from 0 - 7 for the 8 frames
*/
/**************************************************************************/
void Adafruit_IS31FL3731::displayFrame(uint8_t frame) {
if (frame > 7)
frame = 0;
writeRegister8(ISSI_BANK_FUNCTIONREG, ISSI_REG_PICTUREFRAME, frame);
}
/**************************************************************************/
/*!
@brief Switch to a given bank in the chip memory for future reads
@param bank The IS31 bank to switch to
@returns False if I2C command failed to be ack'd
*/
/**************************************************************************/
bool Adafruit_IS31FL3731::selectBank(uint8_t bank) {
uint8_t cmd[2] = {ISSI_COMMANDREGISTER, bank};
return _i2c_dev->write(cmd, 2);
}
/**************************************************************************/
/*!
@brief Enable the audio 'sync' for brightness pulsing (not really tested)
@param sync True to enable, False to disable
*/
/**************************************************************************/
void Adafruit_IS31FL3731::audioSync(bool sync) {
if (sync) {
writeRegister8(ISSI_BANK_FUNCTIONREG, ISSI_REG_AUDIOSYNC, 0x1);
} else {
writeRegister8(ISSI_BANK_FUNCTIONREG, ISSI_REG_AUDIOSYNC, 0x0);
}
}
/**************************************************************************/
/*!
@brief Write one byte to a register located in a given bank
@param bank The IS31 bank to write the register location
@param reg the offset into the bank to write
@param data The byte value
@returns False if I2C command failed to be ack'd
*/
/**************************************************************************/
bool Adafruit_IS31FL3731::writeRegister8(uint8_t bank, uint8_t reg,
uint8_t data) {
selectBank(bank);
uint8_t cmd[2] = {reg, data};
return _i2c_dev->write(cmd, 2);
}
/**************************************************************************/
/*!
@brief Read one byte from a register located in a given bank
@param bank The IS31 bank to read the register location
@param reg the offset into the bank to read
@return 1 byte value
*/
/**************************************************************************/
uint8_t Adafruit_IS31FL3731::readRegister8(uint8_t bank, uint8_t reg) {
uint8_t val = 0xFF;
selectBank(bank);
_i2c_dev->write_then_read(®, 1, &val, 1);
return val;
}
Was siehst Du?