aufgaben weil vergesen zu commiten

This commit is contained in:
danielvici123
2025-04-02 11:33:52 +02:00
parent 6ee3cb1211
commit 51468e220a
52 changed files with 1269 additions and 622 deletions

View File

@@ -0,0 +1,54 @@
/* KA3 2025-03-28 Vorlage Aufgabe 1, Teil 2 bis 3
* I2C-Bus, Temperaturmessung und LED-Ansteuerung */
#include <Wire.h>
// LED0 LED1 LED2 LED3
byte Muster[ ] = {0b0000001, 0b0000011, 0b0000110, 0b0001100, 0b00011000, 0b00110000, 0b01100000, 0b10000000, 0b110000000};
byte LowByte, HighByte;
uint16_t Messwert;
float fTemperatur;
#define lm75_addr 0b1001010
void setup() {
Serial.begin ( 115200 );
Serial.println("DANIEL CWIKLA"); // bitte ändern!
Messwert = 0;
fTemperatur = 0.0;
Wire.begin();
}
void loop() {
// hier kann mit delay gearbeitet werden
Wire.requestFrom(lm75_addr, 2 );
if( Wire.available( ) >= 2 ) {
//Messwert = Wire.read();
HighByte = Wire.read();
LowByte = Wire.read();
//Serial.print("Messwert: ");
//Serial.println(Messwert);
Serial.print("HL Byte:");
fTemperatur = HighByte << LowByte;
Serial.println(fTemperatur);
}
delay(100);
matrix();
}
void matrix(){
Wire.beginTransmission(0b0111011);
// ----------------------------------
// | LEDS low aktiv 0 -> 1 , 1 -> 0 |
// ----------------------------------
Wire.write(0b1111110);
Wire.write(0b1111100);
Wire.write(0b1111001);
Wire.write(0b1110011);
Wire.write(0b11100111);
Wire.write(0b11001111);
Wire.write(0b10011111);
Wire.write(0b10111111);
Wire.write(0b00111111);
Wire.endTransmission();
}

View File

@@ -0,0 +1,28 @@
/* KA3 2025-03-28 Vorlage Aufgabe 2
* AD-Wandler, Kennlinie mit map */
int16_t DigitalWert, Sollwert1, Sollwert2;
uint32_t NextTime = 0, CurrentTime;
void setup() {
Serial.begin(115200);
}
void loop() {
// 2.1) 2x pro Sekunde Analog-Eingang 0 einlesen und ausgeben
CurrentTime = millis();
if (CurrentTime - NextTime >= 1000) {
DigitalWert = analogRead(A0);
Serial.print("Digitalwert: ");
Serial.println(DigitalWert);
NextTime = CurrentTime;
// 2.3) mit map-Funktion in Sollwert1 umrechnen und ausgeben
Sollwert1 = map(DigitalWert, 0, 4095, 285, 3694);
Serial.print("Sollwert1: ");
Serial.println(Sollwert1);
// 2.4) Sollwert2 begrenzen auf 0 bis 1000 und Sollwert1, Sollwert2 ausgeben
Sollwert2 = map(Sollwert1, 285, 3694, 0, 1000);
Serial.print("Sollwert2: ");
Serial.println(Sollwert2);
}
}

View File

@@ -0,0 +1,27 @@
void setup(){
}
void loop(){
Wire.beginTransmission ( I2C_Adresse );
Wire.write( Datenbyte ); // Datenbyte oder Registeradresse
Wire.endTransmission( );
byte Daten1, Daten2, Daten3;
Wire.requestFrom ( I2C_Adresse, 3 ); // Baustein und Anzahl der Bytes
if( Wire.available( ) >= 3 ) {
Daten1 = Wire.read( );
Daten2 = Wire.read( );
Daten3 = Wire.read( );
}
byte Daten1, Daten2, Daten3;
Wire.beginTransmission ( I2C_Adresse );
Wire.write( Registeradresse ); // Auswahl einer internen Registeradresse
Wire.endTransmission( false ); // true oder ( ) sendet ein Stop, false
// sendet kein Stop!
Wire.requestFrom ( I2C_Adresse, 3 );
if( Wire.available( ) >= 3 ) {
Daten1 = Wire.read( );
Daten2 = Wire.read( );
Daten3 = Wire.read( );
}

View File

@@ -0,0 +1,50 @@
// ESP32 Timer Testprogramm
hw_timer_t *MeinTimer = NULL; // beliebiger Name
volatile int Zaehler = 0; // wird in ISR verändert => volatile
uint32_t LastTime = 0;
// ***** Pins deklarieren
const int Taster2=2;
bool bTuWas;
// ****** Funktionsprototypen
void Ruecksetzen ( void );
void Counter ( void );
void setup() {
Serial.begin(115200);
Serial.println("Hello, from ESP32!");
// Pins Konfigurieren
pinMode(Taster2, INPUT); // INPUT_PULLUP bei realer Platine
attachInterrupt(digitalPinToInterrupt(Taster2),&Ruecksetzen,FALLING);
// Timer1 konfigurieren
MeinTimer = timerBegin(1, 80, true); // Timer1, Vorteiler 80, Aufwärts
timerAlarmWrite(MeinTimer, 10000, true);// Alarm 10000 => alle 10ms ein Alarm
timerAttachInterrupt(MeinTimer, &Counter, true); // ISR Counter verknüpfen
timerAlarmEnable(MeinTimer);
timerStart(MeinTimer);
}
void loop() {
// 1 mal pro Sekunde den aktuellen Zählerstand ausgeben:
if( millis()- LastTime >= 1000) {
LastTime = millis();
Serial.println(Zaehler);
}
delay(10); // this speeds up the simulation
}
// Rücksetzen per Taster-Interrupt
void IRAM_ATTR Ruecksetzen ( void ) {
Zaehler =0;
}
// Hochzählen per Timer-Interrrupt
void IRAM_ATTR Counter( void ) {
Zaehler ++;
}

View File

@@ -1758,12 +1758,21 @@ const uint8_t PROGMEM GFXcanvas1::GFXclrBit[] = {0x7F, 0xBF, 0xDF, 0xEF,
@brief Instatiate a GFX 1-bit canvas context for graphics @brief Instatiate a GFX 1-bit canvas context for graphics
@param w Display width, in pixels @param w Display width, in pixels
@param h Display height, in pixels @param h Display height, in pixels
@param allocate_buffer If true, a buffer is allocated with malloc. If
false, the subclass must initialize the buffer before any drawing operation,
and free it in the destructor. If false (the default), the buffer is
allocated and freed by the library.
*/ */
/**************************************************************************/ /**************************************************************************/
GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) { GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h, bool allocate_buffer)
uint32_t bytes = ((w + 7) / 8) * h; : Adafruit_GFX(w, h), buffer_owned(allocate_buffer) {
if ((buffer = (uint8_t *)malloc(bytes))) { if (allocate_buffer) {
memset(buffer, 0, bytes); uint32_t bytes = ((w + 7) / 8) * h;
if ((buffer = (uint8_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
} else {
buffer = nullptr;
} }
} }
@@ -1773,7 +1782,7 @@ GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
*/ */
/**************************************************************************/ /**************************************************************************/
GFXcanvas1::~GFXcanvas1(void) { GFXcanvas1::~GFXcanvas1(void) {
if (buffer) if (buffer && buffer_owned)
free(buffer); free(buffer);
} }
@@ -2111,13 +2120,21 @@ void GFXcanvas1::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
@brief Instatiate a GFX 8-bit canvas context for graphics @brief Instatiate a GFX 8-bit canvas context for graphics
@param w Display width, in pixels @param w Display width, in pixels
@param h Display height, in pixels @param h Display height, in pixels
@param allocate_buffer If true, a buffer is allocated with malloc. If
false, the subclass must initialize the buffer before any drawing operation,
and free it in the destructor. If false (the default), the buffer is
allocated and freed by the library.
*/ */
/**************************************************************************/ /**************************************************************************/
GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) { GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h, bool allocate_buffer)
uint32_t bytes = w * h; : Adafruit_GFX(w, h), buffer_owned(allocate_buffer) {
if ((buffer = (uint8_t *)malloc(bytes))) { if (allocate_buffer) {
memset(buffer, 0, bytes); uint32_t bytes = w * h;
} if ((buffer = (uint8_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
} else
buffer = nullptr;
} }
/**************************************************************************/ /**************************************************************************/
@@ -2126,7 +2143,7 @@ GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
*/ */
/**************************************************************************/ /**************************************************************************/
GFXcanvas8::~GFXcanvas8(void) { GFXcanvas8::~GFXcanvas8(void) {
if (buffer) if (buffer && buffer_owned)
free(buffer); free(buffer);
} }
@@ -2379,12 +2396,21 @@ void GFXcanvas8::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
@brief Instatiate a GFX 16-bit canvas context for graphics @brief Instatiate a GFX 16-bit canvas context for graphics
@param w Display width, in pixels @param w Display width, in pixels
@param h Display height, in pixels @param h Display height, in pixels
@param allocate_buffer If true, a buffer is allocated with malloc. If
false, the subclass must initialize the buffer before any drawing operation,
and free it in the destructor. If false (the default), the buffer is
allocated and freed by the library.
*/ */
/**************************************************************************/ /**************************************************************************/
GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) { GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h, bool allocate_buffer)
uint32_t bytes = w * h * 2; : Adafruit_GFX(w, h), buffer_owned(allocate_buffer) {
if ((buffer = (uint16_t *)malloc(bytes))) { if (allocate_buffer) {
memset(buffer, 0, bytes); uint32_t bytes = w * h * 2;
if ((buffer = (uint16_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
} else {
buffer = nullptr;
} }
} }
@@ -2394,7 +2420,7 @@ GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
*/ */
/**************************************************************************/ /**************************************************************************/
GFXcanvas16::~GFXcanvas16(void) { GFXcanvas16::~GFXcanvas16(void) {
if (buffer) if (buffer && buffer_owned)
free(buffer); free(buffer);
} }

View File

@@ -309,7 +309,7 @@ private:
/// A GFX 1-bit canvas context for graphics /// A GFX 1-bit canvas context for graphics
class GFXcanvas1 : public Adafruit_GFX { class GFXcanvas1 : public Adafruit_GFX {
public: public:
GFXcanvas1(uint16_t w, uint16_t h); GFXcanvas1(uint16_t w, uint16_t h, bool allocate_buffer = true);
~GFXcanvas1(void); ~GFXcanvas1(void);
void drawPixel(int16_t x, int16_t y, uint16_t color); void drawPixel(int16_t x, int16_t y, uint16_t color);
void fillScreen(uint16_t color); void fillScreen(uint16_t color);
@@ -328,7 +328,9 @@ protected:
bool getRawPixel(int16_t x, int16_t y) const; bool getRawPixel(int16_t x, int16_t y) const;
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color); void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
uint8_t *buffer; ///< Raster data: no longer private, allow subclass access uint8_t *buffer; ///< Raster data: no longer private, allow subclass access
bool buffer_owned; ///< If true, destructor will free buffer, else it will do
///< nothing
private: private:
#ifdef __AVR__ #ifdef __AVR__
@@ -340,7 +342,7 @@ private:
/// A GFX 8-bit canvas context for graphics /// A GFX 8-bit canvas context for graphics
class GFXcanvas8 : public Adafruit_GFX { class GFXcanvas8 : public Adafruit_GFX {
public: public:
GFXcanvas8(uint16_t w, uint16_t h); GFXcanvas8(uint16_t w, uint16_t h, bool allocate_buffer = true);
~GFXcanvas8(void); ~GFXcanvas8(void);
void drawPixel(int16_t x, int16_t y, uint16_t color); void drawPixel(int16_t x, int16_t y, uint16_t color);
void fillScreen(uint16_t color); void fillScreen(uint16_t color);
@@ -359,13 +361,15 @@ protected:
uint8_t getRawPixel(int16_t x, int16_t y) const; uint8_t getRawPixel(int16_t x, int16_t y) const;
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color); void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
uint8_t *buffer; ///< Raster data: no longer private, allow subclass access uint8_t *buffer; ///< Raster data: no longer private, allow subclass access
bool buffer_owned; ///< If true, destructor will free buffer, else it will do
///< nothing
}; };
/// A GFX 16-bit canvas context for graphics /// A GFX 16-bit canvas context for graphics
class GFXcanvas16 : public Adafruit_GFX { class GFXcanvas16 : public Adafruit_GFX {
public: public:
GFXcanvas16(uint16_t w, uint16_t h); GFXcanvas16(uint16_t w, uint16_t h, bool allocate_buffer = true);
~GFXcanvas16(void); ~GFXcanvas16(void);
void drawPixel(int16_t x, int16_t y, uint16_t color); void drawPixel(int16_t x, int16_t y, uint16_t color);
void fillScreen(uint16_t color); void fillScreen(uint16_t color);
@@ -385,7 +389,9 @@ protected:
uint16_t getRawPixel(int16_t x, int16_t y) const; uint16_t getRawPixel(int16_t x, int16_t y) const;
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color); void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
uint16_t *buffer; ///< Raster data: no longer private, allow subclass access uint16_t *buffer; ///< Raster data: no longer private, allow subclass access
bool buffer_owned; ///< If true, destructor will free buffer, else it will do
///< nothing
}; };
#endif // _ADAFRUIT_GFX_H #endif // _ADAFRUIT_GFX_H

View File

@@ -62,7 +62,7 @@
allocation is performed there! allocation is performed there!
*/ */
Adafruit_GrayOLED::Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h, Adafruit_GrayOLED::Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h,
TwoWire *twi, int8_t rst_pin, TwoWire *twi, int16_t rst_pin,
uint32_t clkDuring, uint32_t clkAfter) uint32_t clkDuring, uint32_t clkAfter)
: Adafruit_GFX(w, h), i2c_preclk(clkDuring), i2c_postclk(clkAfter), : Adafruit_GFX(w, h), i2c_preclk(clkDuring), i2c_postclk(clkAfter),
buffer(NULL), dcPin(-1), csPin(-1), rstPin(rst_pin), _bpp(bpp) { buffer(NULL), dcPin(-1), csPin(-1), rstPin(rst_pin), _bpp(bpp) {
@@ -98,9 +98,9 @@ Adafruit_GrayOLED::Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h,
allocation is performed there! allocation is performed there!
*/ */
Adafruit_GrayOLED::Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h, Adafruit_GrayOLED::Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h,
int8_t mosi_pin, int8_t sclk_pin, int16_t mosi_pin, int16_t sclk_pin,
int8_t dc_pin, int8_t rst_pin, int16_t dc_pin, int16_t rst_pin,
int8_t cs_pin) int16_t cs_pin)
: Adafruit_GFX(w, h), dcPin(dc_pin), csPin(cs_pin), rstPin(rst_pin), : Adafruit_GFX(w, h), dcPin(dc_pin), csPin(cs_pin), rstPin(rst_pin),
_bpp(bpp) { _bpp(bpp) {
@@ -134,8 +134,8 @@ Adafruit_GrayOLED::Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h,
allocation is performed there! allocation is performed there!
*/ */
Adafruit_GrayOLED::Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h, Adafruit_GrayOLED::Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h,
SPIClass *spi, int8_t dc_pin, SPIClass *spi, int16_t dc_pin,
int8_t rst_pin, int8_t cs_pin, int16_t rst_pin, int16_t cs_pin,
uint32_t bitrate) uint32_t bitrate)
: Adafruit_GFX(w, h), dcPin(dc_pin), csPin(cs_pin), rstPin(rst_pin), : Adafruit_GFX(w, h), dcPin(dc_pin), csPin(cs_pin), rstPin(rst_pin),
_bpp(bpp) { _bpp(bpp) {

View File

@@ -48,13 +48,13 @@
class Adafruit_GrayOLED : public Adafruit_GFX { class Adafruit_GrayOLED : public Adafruit_GFX {
public: public:
Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h, TwoWire *twi = &Wire, Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h, TwoWire *twi = &Wire,
int8_t rst_pin = -1, uint32_t preclk = 400000, int16_t rst_pin = -1, uint32_t preclk = 400000,
uint32_t postclk = 100000); uint32_t postclk = 100000);
Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h, int8_t mosi_pin, Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h, int16_t mosi_pin,
int8_t sclk_pin, int8_t dc_pin, int8_t rst_pin, int16_t sclk_pin, int16_t dc_pin, int16_t rst_pin,
int8_t cs_pin); int16_t cs_pin);
Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h, SPIClass *spi, Adafruit_GrayOLED(uint8_t bpp, uint16_t w, uint16_t h, SPIClass *spi,
int8_t dc_pin, int8_t rst_pin, int8_t cs_pin, int16_t dc_pin, int16_t rst_pin, int16_t cs_pin,
uint32_t bitrate = 8000000UL); uint32_t bitrate = 8000000UL);
~Adafruit_GrayOLED(void); ~Adafruit_GrayOLED(void);

View File

@@ -17,9 +17,10 @@
* @section dependencies Dependencies * @section dependencies Dependencies
* *
* This library depends on <a href="https://github.com/adafruit/Adafruit_GFX"> * This library depends on
* Adafruit_GFX</a> being present on your system. Please make sure you have * <a href="https://github.com/adafruit/Adafruit-GFX-Library">Adafruit_GFX</a>
* installed the latest version before using this library. * being present on your system. Please make sure you have installed the latest
* version before using this library.
* *
* @section author Author * @section author Author
* *
@@ -40,6 +41,13 @@
#if defined(__AVR_XMEGA__) // only tested with __AVR_ATmega4809__ #if defined(__AVR_XMEGA__) // only tested with __AVR_ATmega4809__
#define AVR_WRITESPI(x) \ #define AVR_WRITESPI(x) \
for (SPI0_DATA = (x); (!(SPI0_INTFLAGS & _BV(SPI_IF_bp)));) for (SPI0_DATA = (x); (!(SPI0_INTFLAGS & _BV(SPI_IF_bp)));)
#elif defined(__LGT8F__)
#define AVR_WRITESPI(x) \
SPDR = (x); \
asm volatile("nop"); \
while ((SPFR & _BV(RDEMPT))) \
; \
SPFR = _BV(RDEMPT) | _BV(WREMPT)
#else #else
#define AVR_WRITESPI(x) for (SPDR = (x); (!(SPSR & _BV(SPIF)));) #define AVR_WRITESPI(x) for (SPDR = (x); (!(SPSR & _BV(SPIF)));)
#endif #endif
@@ -871,7 +879,7 @@ void Adafruit_SPITFT::initSPI(uint32_t freq, uint8_t spiMode) {
DMA_ADDRESS_INCREMENT_STEP_SIZE_1; DMA_ADDRESS_INCREMENT_STEP_SIZE_1;
descriptor[d].DSTADDR.reg = (uint32_t)tft8.writePort; descriptor[d].DSTADDR.reg = (uint32_t)tft8.writePort;
} }
#endif // __SAMD51 #endif // __SAMD51
} // end parallel-specific DMA setup } // end parallel-specific DMA setup
lastFillColor = 0x0000; lastFillColor = 0x0000;
@@ -879,13 +887,13 @@ void Adafruit_SPITFT::initSPI(uint32_t freq, uint8_t spiMode) {
dma.setCallback(dma_callback); dma.setCallback(dma_callback);
return; // Success! return; // Success!
// else clean up any partial allocation... // else clean up any partial allocation...
} // end descriptor memalign() } // end descriptor memalign()
free(pixelBuf[0]); free(pixelBuf[0]);
pixelBuf[0] = pixelBuf[1] = NULL; pixelBuf[0] = pixelBuf[1] = NULL;
} // end pixelBuf malloc() } // end pixelBuf malloc()
// Don't currently have a descriptor delete function in // Don't currently have a descriptor delete function in
// ZeroDMA lib, but if we did, it would be called here. // ZeroDMA lib, but if we did, it would be called here.
} // end addDescriptor() } // end addDescriptor()
dma.free(); // Deallocate DMA channel dma.free(); // Deallocate DMA channel
} }
#endif // end USE_SPI_DMA #endif // end USE_SPI_DMA
@@ -1365,11 +1373,11 @@ void Adafruit_SPITFT::writeColor(uint16_t color, uint32_t len) {
dma.trigger(); dma.trigger();
while (dma_busy) while (dma_busy)
; // Wait for completion ; // Wait for completion
// Unfortunately blocking is necessary. An earlier version returned // Unfortunately blocking is necessary. An earlier version returned
// immediately and checked dma_busy on startWrite() instead, but it // immediately and checked dma_busy on startWrite() instead, but it
// turns out to be MUCH slower on many graphics operations (as when // turns out to be MUCH slower on many graphics operations (as when
// drawing lines, pixel-by-pixel), perhaps because it's a volatile // drawing lines, pixel-by-pixel), perhaps because it's a volatile
// type and doesn't cache. Working on this. // type and doesn't cache. Working on this.
#if defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO) #if defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO)
if (connection == TFT_HARD_SPI) { if (connection == TFT_HARD_SPI) {
// SAMD51: SPI DMA seems to leave the SPI peripheral in a freaky // SAMD51: SPI DMA seems to leave the SPI peripheral in a freaky
@@ -2081,9 +2089,9 @@ uint16_t Adafruit_SPITFT::readcommand16(uint16_t addr) {
result = *(volatile uint16_t *)tft8.readPort; // 16-bit read result = *(volatile uint16_t *)tft8.readPort; // 16-bit read
*(volatile uint16_t *)tft8.dirSet = 0xFFFF; // Output state *(volatile uint16_t *)tft8.dirSet = 0xFFFF; // Output state
#else // !HAS_PORT_SET_CLR #else // !HAS_PORT_SET_CLR
*(volatile uint16_t *)tft8.portDir = 0x0000; // Input state *(volatile uint16_t *)tft8.portDir = 0x0000; // Input state
result = *(volatile uint16_t *)tft8.readPort; // 16-bit read result = *(volatile uint16_t *)tft8.readPort; // 16-bit read
*(volatile uint16_t *)tft8.portDir = 0xFFFF; // Output state *(volatile uint16_t *)tft8.portDir = 0xFFFF; // Output state
#endif // end !HAS_PORT_SET_CLR #endif // end !HAS_PORT_SET_CLR
TFT_RD_HIGH(); // Read line HIGH TFT_RD_HIGH(); // Read line HIGH
endWrite(); endWrite();
@@ -2238,17 +2246,17 @@ uint8_t Adafruit_SPITFT::spiRead(void) {
w = *tft8.readPort; // Read value from port w = *tft8.readPort; // Read value from port
*tft8.portDir = 0xFF; // Restore port to output *tft8.portDir = 0xFF; // Restore port to output
#else // !__AVR__ #else // !__AVR__
if (!tft8.wide) { // 8-bit TFT connection if (!tft8.wide) { // 8-bit TFT connection
#if defined(HAS_PORT_SET_CLR) #if defined(HAS_PORT_SET_CLR)
*tft8.dirClr = 0xFF; // Set port to input state *tft8.dirClr = 0xFF; // Set port to input state
w = *tft8.readPort; // Read value from port w = *tft8.readPort; // Read value from port
*tft8.dirSet = 0xFF; // Restore port to output *tft8.dirSet = 0xFF; // Restore port to output
#else // !HAS_PORT_SET_CLR #else // !HAS_PORT_SET_CLR
*tft8.portDir = 0x00; // Set port to input state *tft8.portDir = 0x00; // Set port to input state
w = *tft8.readPort; // Read value from port w = *tft8.readPort; // Read value from port
*tft8.portDir = 0xFF; // Restore port to output *tft8.portDir = 0xFF; // Restore port to output
#endif // end HAS_PORT_SET_CLR #endif // end HAS_PORT_SET_CLR
} else { // 16-bit TFT connection } else { // 16-bit TFT connection
#if defined(HAS_PORT_SET_CLR) #if defined(HAS_PORT_SET_CLR)
*(volatile uint16_t *)tft8.dirClr = 0xFFFF; // Input state *(volatile uint16_t *)tft8.dirClr = 0xFFFF; // Input state
w = *(volatile uint16_t *)tft8.readPort; // 16-bit read w = *(volatile uint16_t *)tft8.readPort; // 16-bit read
@@ -2259,7 +2267,7 @@ uint8_t Adafruit_SPITFT::spiRead(void) {
*(volatile uint16_t *)tft8.portDir = 0xFFFF; // Output state *(volatile uint16_t *)tft8.portDir = 0xFFFF; // Output state
#endif // end !HAS_PORT_SET_CLR #endif // end !HAS_PORT_SET_CLR
} }
TFT_RD_HIGH(); // Read line HIGH TFT_RD_HIGH(); // Read line HIGH
#endif // end !__AVR__ #endif // end !__AVR__
#else // !USE_FAST_PINIO #else // !USE_FAST_PINIO
w = 0; // Parallel TFT is NOT SUPPORTED without USE_FAST_PINIO w = 0; // Parallel TFT is NOT SUPPORTED without USE_FAST_PINIO

View File

@@ -32,8 +32,8 @@
typedef uint8_t ADAGFX_PORT_t; ///< PORT values are 8-bit typedef uint8_t ADAGFX_PORT_t; ///< PORT values are 8-bit
#define USE_FAST_PINIO ///< Use direct PORT register access #define USE_FAST_PINIO ///< Use direct PORT register access
#elif defined(ARDUINO_STM32_FEATHER) // WICED #elif defined(ARDUINO_STM32_FEATHER) // WICED
typedef class HardwareSPI SPIClass; ///< SPI is a bit odd on WICED typedef class HardwareSPI SPIClass; ///< SPI is a bit odd on WICED
typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
#elif defined(__arm__) #elif defined(__arm__)
#if defined(ARDUINO_ARCH_SAMD) #if defined(ARDUINO_ARCH_SAMD)
// Adafruit M0, M4 // Adafruit M0, M4
@@ -66,7 +66,7 @@ typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
#endif // end !ARM #endif // end !ARM
typedef volatile ADAGFX_PORT_t *PORTreg_t; ///< PORT register type typedef volatile ADAGFX_PORT_t *PORTreg_t; ///< PORT register type
#if defined(__AVR__) #if defined(__AVR__) && !defined(__LGT8F__)
#define DEFAULT_SPI_FREQ 8000000L ///< Hardware SPI default speed #define DEFAULT_SPI_FREQ 8000000L ///< Hardware SPI default speed
#else #else
#define DEFAULT_SPI_FREQ 16000000L ///< Hardware SPI default speed #define DEFAULT_SPI_FREQ 16000000L ///< Hardware SPI default speed
@@ -79,8 +79,8 @@ typedef volatile ADAGFX_PORT_t *PORTreg_t; ///< PORT register type
defined(ADAFRUIT_CIRCUITPLAYGROUND_M0) defined(ADAFRUIT_CIRCUITPLAYGROUND_M0)
#define USE_SPI_DMA ///< Auto DMA #define USE_SPI_DMA ///< Auto DMA
#else #else
//#define USE_SPI_DMA ///< If set, // #define USE_SPI_DMA ///< If set,
// use DMA if available // use DMA if available
#endif #endif
// Another "oops" name -- this now also handles parallel DMA. // Another "oops" name -- this now also handles parallel DMA.
// If DMA is enabled, Arduino sketch MUST #include <Adafruit_ZeroDMA.h> // If DMA is enabled, Arduino sketch MUST #include <Adafruit_ZeroDMA.h>
@@ -397,8 +397,8 @@ protected:
PORTreg_t dcPortSet; ///< PORT register for data/command SET PORTreg_t dcPortSet; ///< PORT register for data/command SET
PORTreg_t dcPortClr; ///< PORT register for data/command CLEAR PORTreg_t dcPortClr; ///< PORT register for data/command CLEAR
#else // !HAS_PORT_SET_CLR #else // !HAS_PORT_SET_CLR
PORTreg_t csPort; ///< PORT register for chip select PORTreg_t csPort; ///< PORT register for chip select
PORTreg_t dcPort; ///< PORT register for data/command PORTreg_t dcPort; ///< PORT register for data/command
#endif // end HAS_PORT_SET_CLR #endif // end HAS_PORT_SET_CLR
#endif // end USE_FAST_PINIO #endif // end USE_FAST_PINIO
#if defined(__cplusplus) && (__cplusplus >= 201100) #if defined(__cplusplus) && (__cplusplus >= 201100)
@@ -448,8 +448,8 @@ protected:
volatile uint32_t *writePort; ///< PORT register for DATA WRITE volatile uint32_t *writePort; ///< PORT register for DATA WRITE
volatile uint32_t *readPort; ///< PORT (PIN) register for DATA READ volatile uint32_t *readPort; ///< PORT (PIN) register for DATA READ
#else #else
volatile uint8_t *writePort; ///< PORT register for DATA WRITE volatile uint8_t *writePort; ///< PORT register for DATA WRITE
volatile uint8_t *readPort; ///< PORT (PIN) register for DATA READ volatile uint8_t *readPort; ///< PORT (PIN) register for DATA READ
#endif #endif
#if defined(HAS_PORT_SET_CLR) #if defined(HAS_PORT_SET_CLR)
// Port direction register pointers are always 8-bit regardless of // Port direction register pointers are always 8-bit regardless of
@@ -508,10 +508,10 @@ protected:
ADAGFX_PORT_t dcPinMask; ///< Bitmask for data/command ADAGFX_PORT_t dcPinMask; ///< Bitmask for data/command
#endif // end !KINETISK #endif // end !KINETISK
#else // !HAS_PORT_SET_CLR #else // !HAS_PORT_SET_CLR
ADAGFX_PORT_t csPinMaskSet; ///< Bitmask for chip select SET (OR) ADAGFX_PORT_t csPinMaskSet; ///< Bitmask for chip select SET (OR)
ADAGFX_PORT_t csPinMaskClr; ///< Bitmask for chip select CLEAR (AND) ADAGFX_PORT_t csPinMaskClr; ///< Bitmask for chip select CLEAR (AND)
ADAGFX_PORT_t dcPinMaskSet; ///< Bitmask for data/command SET (OR) ADAGFX_PORT_t dcPinMaskSet; ///< Bitmask for data/command SET (OR)
ADAGFX_PORT_t dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND) ADAGFX_PORT_t dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND)
#endif // end HAS_PORT_SET_CLR #endif // end HAS_PORT_SET_CLR
#endif // end USE_FAST_PINIO #endif // end USE_FAST_PINIO
uint8_t connection; ///< TFT_HARD_SPI, TFT_SOFT_SPI, etc. uint8_t connection; ///< TFT_HARD_SPI, TFT_SOFT_SPI, etc.

View File

@@ -1,5 +1,5 @@
name=Adafruit GFX Library name=Adafruit GFX Library
version=1.11.11 version=1.12.0
author=Adafruit author=Adafruit
maintainer=Adafruit <info@adafruit.com> maintainer=Adafruit <info@adafruit.com>
sentence=Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from. sentence=Adafruit GFX graphics core library, this is the 'core' class that all our other graphics libraries derive from.

View File

@@ -1,32 +1,29 @@
License Agreement Janelia Open-Source Software
(3-clause BSD License) (3-clause BSD License)
Janelia Research Campus Software Copyright 1.1
Copyright (c) 2014, Howard Hughes Medical Institute Copyright (c) 2021 Howard Hughes Medical Institute
All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without modification,
modification, are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer. list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, * Redistributions in binary form must reproduce the above copyright notice, this
this list of conditions and the following disclaimer in the documentation list of conditions and the following disclaimer in the documentation and/or
and/or other materials provided with the distribution. other materials provided with the distribution.
* Neither the name of the Howard Hughes Medical Institute nor the * Neither the name of HHMI nor the names of its contributors may be used to
names of its contributors may be used to endorse or promote products endorse or promote products derived from this software without specific prior
derived from this software without specific prior written written permission.
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS” AND
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,16 +1,21 @@
#+TITLE: PCA9685 #+TITLE: PCA9685
#+AUTHOR: Peter Polidoro #+AUTHOR: Peter Polidoro
#+EMAIL: peterpolidoro@gmail.com #+EMAIL: peter@polidoro.io
* Library Information * Library Information
- Name :: PCA9685 - Name :: PCA9685
- Version :: 2.1.4 - Version :: 3.0.2
- License :: BSD - License :: BSD
- URL :: https://github.com/janelia-arduino/PCA9685 - URL :: https://github.com/janelia-arduino/PCA9685
- Author :: Peter Polidoro - Author :: Peter Polidoro
- Email :: peterpolidoro@gmail.com - Email :: peter@polidoro.io
The PCA9685 is a 16-channel 12-bit PWM controller. All channels operate at a ** Description
programmable frequency between roughly 25 to 1600 Hz with 16 independent
12-bit duty cycles from 0 to 100%. Supports using a single device (for up to The PCA9685 is a 16-channel 12-bit PWM controller.
16 channels) or up to 55 devices (for up to 880 channels).
All channels operate at a programmable frequency between roughly 25 to 1600 Hz
with 16 independent 12-bit duty cycles from 0 to 100%.
Supports using a single device (for up to 16 channels) or up to 55 devices
(for up to 880 channels).

Binary file not shown.

View File

@@ -3,16 +3,16 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "Constants.h" #include "Constants.h"
namespace constants namespace constants
{ {
const uint8_t device_address = 0x40; const PCA9685::DeviceAddress device_address = 0x40;
const size_t output_enable_pin = 2; const PCA9685::Pin output_enable_pin = 2;
const size_t loop_delay = 100; const size_t loop_delay = 100;
const uint16_t frequency_increment = 10; const PCA9685::Frequency frequency_increment = 10;
} }

View File

@@ -3,19 +3,20 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef CONSTANTS_H #ifndef CONSTANTS_H
#define CONSTANTS_H #define CONSTANTS_H
#include <Arduino.h> #include <Arduino.h>
#include <PCA9685.h>
namespace constants namespace constants
{ {
extern const uint8_t device_address; extern const PCA9685::DeviceAddress device_address;
extern const size_t output_enable_pin; extern const PCA9685::Pin output_enable_pin;
extern const size_t loop_delay; extern const size_t loop_delay;
extern const uint16_t frequency_increment; extern const PCA9685::Frequency frequency_increment;
} }
#endif #endif

View File

@@ -6,9 +6,9 @@
PCA9685 pca9685; PCA9685 pca9685;
uint16_t frequency_min; PCA9685::Frequency frequency_min;
uint16_t frequency_max; PCA9685::Frequency frequency_max;
uint16_t frequency; PCA9685::Frequency frequency;
void setup() void setup()
{ {
@@ -19,8 +19,8 @@ void setup()
pca9685.setOutputsNotInverted(); pca9685.setOutputsNotInverted();
uint16_t time_min = pca9685.getTimeMin(); PCA9685::Time time_min = pca9685.getTimeMin();
uint16_t time_max = pca9685.getTimeMax(); PCA9685::Time time_max = pca9685.getTimeMax();
pca9685.setAllChannelsOnAndOffTime(time_min,time_max/4); pca9685.setAllChannelsOnAndOffTime(time_min,time_max/4);
frequency_min = pca9685.getFrequencyMin(); frequency_min = pca9685.getFrequencyMin();

View File

@@ -3,19 +3,19 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "Constants.h" #include "Constants.h"
namespace constants namespace constants
{ {
const uint8_t device_address = 0x40; const PCA9685::DeviceAddress device_address = 0x40;
const size_t output_enable_pin = 2; const PCA9685::Pin output_enable_pin = 2;
const size_t loop_delay = 100; const size_t loop_delay = 100;
const uint16_t frequency = 200; const PCA9685::Frequency frequency = 200;
const uint16_t time_increment = 100; const PCA9685::Time time_increment = 100;
const uint8_t channel = 0; const PCA9685::Channel channel = 0;
} }

View File

@@ -3,22 +3,23 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef CONSTANTS_H #ifndef CONSTANTS_H
#define CONSTANTS_H #define CONSTANTS_H
#include <Arduino.h> #include <Arduino.h>
#include <PCA9685.h>
namespace constants namespace constants
{ {
extern const uint8_t device_address; extern const PCA9685::DeviceAddress device_address;
extern const size_t output_enable_pin; extern const PCA9685::Pin output_enable_pin;
extern const size_t loop_delay; extern const size_t loop_delay;
extern const uint16_t frequency; extern const PCA9685::Frequency frequency;
extern const uint16_t time_increment; extern const PCA9685::Time time_increment;
extern const uint8_t channel; extern const PCA9685::Channel channel;
} }
#endif #endif

View File

@@ -6,9 +6,9 @@
PCA9685 pca9685; PCA9685 pca9685;
uint16_t time_min; PCA9685::Time time_min;
uint16_t time_max; PCA9685::Time time_max;
uint16_t off_time; PCA9685::Time off_time;
void setup() void setup()
{ {

View File

@@ -3,26 +3,26 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "Constants.h" #include "Constants.h"
namespace constants namespace constants
{ {
const uint8_t device_addresses[DEVICE_COUNT] = const PCA9685::DeviceAddress device_addresses[DEVICE_COUNT] =
{ {
0x40, 0x40,
0x41, 0x41,
0x42 0x42
}; };
const uint8_t device_index = 0; const PCA9685::DeviceIndex = 0;
const size_t output_enable_pin = 2; const PCA9685::Pin output_enable_pin = 2;
const size_t loop_delay = 100; const size_t loop_delay = 100;
const uint16_t frequency = 200; const PCA9685::Frequency frequency = 200;
const uint16_t time_increment = 100; const PCA9685::Time time_increment = 100;
const uint8_t channel = 0; const PCA9685::Channel channel = 0;
} }

View File

@@ -3,25 +3,26 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef CONSTANTS_H #ifndef CONSTANTS_H
#define CONSTANTS_H #define CONSTANTS_H
#include <Arduino.h> #include <Arduino.h>
#include <PCA9685.h>
namespace constants namespace constants
{ {
enum{DEVICE_COUNT=3}; enum{DEVICE_COUNT=3};
extern const uint8_t device_addresses[DEVICE_COUNT]; extern const PCA9685::DeviceAddress device_addresses[DEVICE_COUNT];
extern const uint8_t device_index; extern const PCA9685::DeviceIndex;
extern const size_t output_enable_pin; extern const PCA9685::Pin output_enable_pin;
extern const size_t loop_delay; extern const size_t loop_delay;
extern const uint16_t frequency; extern const PCA9685::Frequency frequency;
extern const uint16_t time_increment; extern const PCA9685::Time time_increment;
extern const uint8_t channel; extern const PCA9685::Channel channel;
} }
#endif #endif

View File

@@ -6,14 +6,14 @@
PCA9685 pca9685; PCA9685 pca9685;
uint16_t time_min; PCA9685::Time time_min;
uint16_t time_max; PCA9685::Time time_max;
uint16_t on_time; PCA9685::Time on_time;
void setup() void setup()
{ {
pca9685.setWire(Wire); pca9685.setWire(Wire);
for (uint8_t device_index=0; device_index<constants::DEVICE_COUNT; ++device_index) for (PCA9685::DeviceIndex=0; device_index<constants::DEVICE_COUNT; ++device_index)
{ {
pca9685.addDevice(constants::device_addresses[device_index]); pca9685.addDevice(constants::device_addresses[device_index]);
} }

View File

@@ -3,21 +3,21 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "Constants.h" #include "Constants.h"
namespace constants namespace constants
{ {
const uint8_t device_address = 0x40; const PCA9685::DeviceAddress device_address = 0x40;
const size_t output_enable_pin = 2; const PCA9685::Pin output_enable_pin = 2;
const size_t loop_delay = 100; const size_t loop_delay = 100;
const uint8_t channel = 0; const PCA9685::Channel channel = 0;
const uint16_t servo_pulse_duration_min = 900; const PCA9685::DurationMicroseconds servo_pulse_duration_min = 900;
const uint16_t servo_pulse_duration_max = 2100; const PCA9685::DurationMicroseconds servo_pulse_duration_max = 2100;
const uint16_t servo_pulse_duration_increment = 100; const PCA9685::DurationMicroseconds servo_pulse_duration_increment = 100;
} }

View File

@@ -3,24 +3,25 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef CONSTANTS_H #ifndef CONSTANTS_H
#define CONSTANTS_H #define CONSTANTS_H
#include <Arduino.h> #include <Arduino.h>
#include <PCA9685.h>
namespace constants namespace constants
{ {
extern const uint8_t device_address; extern const PCA9685::DeviceAddress device_address;
extern const size_t output_enable_pin; extern const PCA9685::Pin output_enable_pin;
extern const size_t loop_delay; extern const size_t loop_delay;
extern const uint8_t channel; extern const PCA9685::Channel channel;
extern const uint16_t servo_pulse_duration_min; extern const PCA9685::DurationMicroseconds servo_pulse_duration_min;
extern const uint16_t servo_pulse_duration_max; extern const PCA9685::DurationMicroseconds servo_pulse_duration_max;
extern const uint16_t servo_pulse_duration_increment; extern const PCA9685::DurationMicroseconds servo_pulse_duration_increment;
} }
#endif #endif

View File

@@ -6,7 +6,7 @@
PCA9685 pca9685; PCA9685 pca9685;
uint16_t servo_pulse_duration; PCA9685::DurationMicroseconds servo_pulse_duration;
void setup() void setup()
{ {

View File

@@ -3,19 +3,19 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "Constants.h" #include "Constants.h"
namespace constants namespace constants
{ {
const uint8_t device_address = 0x40; const PCA9685::DeviceAddress device_address = 0x40;
const size_t output_enable_pin = 2; const PCA9685::Pin output_enable_pin = 2;
const size_t loop_delay = 8000; const size_t loop_delay = 8000;
const uint16_t frequency = 200; const PCA9685::Frequency frequency = 200;
const uint8_t channel = 0; const PCA9685::Channel channel = 0;
const Example examples[EXAMPLE_COUNT] = const Example examples[EXAMPLE_COUNT] =
{ {

View File

@@ -3,28 +3,29 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef CONSTANTS_H #ifndef CONSTANTS_H
#define CONSTANTS_H #define CONSTANTS_H
#include <Arduino.h> #include <Arduino.h>
#include <PCA9685.h>
namespace constants namespace constants
{ {
extern const uint8_t device_address; extern const PCA9685::DeviceAddress device_address;
extern const size_t output_enable_pin; extern const PCA9685::Pin output_enable_pin;
extern const size_t loop_delay; extern const size_t loop_delay;
extern const uint16_t frequency; extern const PCA9685::Frequency frequency;
extern const uint8_t channel; extern const PCA9685::Channel channel;
enum{EXAMPLE_COUNT=4}; enum{EXAMPLE_COUNT=4};
struct Example struct Example
{ {
double duty_cycle; PCA9685::Percent duty_cycle;
double percent_delay; PCA9685::Percent percent_delay;
}; };
extern const Example examples[EXAMPLE_COUNT]; extern const Example examples[EXAMPLE_COUNT];

View File

@@ -3,19 +3,19 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "Constants.h" #include "Constants.h"
namespace constants namespace constants
{ {
const uint8_t device_address = 0x40; const PCA9685::DeviceAddress device_address = 0x40;
const size_t output_enable_pin = 2; const PCA9685::Pin output_enable_pin = 2;
const size_t loop_delay = 8000; const size_t loop_delay = 8000;
const uint16_t frequency = 200; const PCA9685::Frequency frequency = 200;
const uint8_t channel = 0; const PCA9685::Channel channel = 0;
const Example examples[EXAMPLE_COUNT] = const Example examples[EXAMPLE_COUNT] =
{ {

View File

@@ -3,28 +3,29 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef CONSTANTS_H #ifndef CONSTANTS_H
#define CONSTANTS_H #define CONSTANTS_H
#include <Arduino.h> #include <Arduino.h>
#include <PCA9685.h>
namespace constants namespace constants
{ {
extern const uint8_t device_address; extern const PCA9685::DeviceAddress device_address;
extern const size_t output_enable_pin; extern const PCA9685::Pin output_enable_pin;
extern const size_t loop_delay; extern const size_t loop_delay;
extern const uint16_t frequency; extern const PCA9685::Frequency frequency;
extern const uint8_t channel; extern const PCA9685::Channel channel;
enum{EXAMPLE_COUNT=4}; enum{EXAMPLE_COUNT=4};
struct Example struct Example
{ {
uint16_t on_time; PCA9685::Time on_time;
uint16_t off_time; PCA9685::Time off_time;
}; };
extern const Example examples[EXAMPLE_COUNT]; extern const Example examples[EXAMPLE_COUNT];

View File

@@ -3,19 +3,19 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "Constants.h" #include "Constants.h"
namespace constants namespace constants
{ {
const uint8_t device_address = 0x40; const PCA9685::DeviceAddress device_address = 0x40;
const size_t output_enable_pin = 2; const PCA9685::Pin output_enable_pin = 2;
const size_t loop_delay = 8000; const size_t loop_delay = 8000;
const uint16_t frequency = 200; const PCA9685::Frequency frequency = 200;
const uint8_t channel = 0; const PCA9685::Channel channel = 0;
const Example examples[EXAMPLE_COUNT] = const Example examples[EXAMPLE_COUNT] =
{ {

View File

@@ -3,28 +3,29 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef CONSTANTS_H #ifndef CONSTANTS_H
#define CONSTANTS_H #define CONSTANTS_H
#include <Arduino.h> #include <Arduino.h>
#include <PCA9685.h>
namespace constants namespace constants
{ {
extern const uint8_t device_address; extern const PCA9685::DeviceAddress device_address;
extern const size_t output_enable_pin; extern const PCA9685::Pin output_enable_pin;
extern const size_t loop_delay; extern const size_t loop_delay;
extern const uint16_t frequency; extern const PCA9685::Frequency frequency;
extern const uint8_t channel; extern const PCA9685::Channel channel;
enum{EXAMPLE_COUNT=4}; enum{EXAMPLE_COUNT=4};
struct Example struct Example
{ {
uint16_t pulse_width; PCA9685::Duration pulse_width;
uint16_t phase_shift; PCA9685::Duration phase_shift;
}; };
extern const Example examples[EXAMPLE_COUNT]; extern const Example examples[EXAMPLE_COUNT];

View File

@@ -3,20 +3,20 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "Constants.h" #include "Constants.h"
namespace constants namespace constants
{ {
const uint8_t device_address = 0x40; const PCA9685::DeviceAddress device_address = 0x40;
const size_t output_enable_pin = 2; const PCA9685::Pin output_enable_pin = 2;
const long baud = 115200; const long baud = 115200;
const size_t loop_delay = 100; const size_t loop_delay = 100;
const uint16_t frequency = 200; const PCA9685::Frequency frequency = 200;
const uint16_t time_increment = 400; const PCA9685::Time time_increment = 400;
const double epsilon = 0.001; const PCA9685::Percent epsilon = 0.001;
} }

View File

@@ -3,22 +3,23 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef CONSTANTS_H #ifndef CONSTANTS_H
#define CONSTANTS_H #define CONSTANTS_H
#include <Arduino.h> #include <Arduino.h>
#include <PCA9685.h>
namespace constants namespace constants
{ {
extern const uint8_t device_address; extern const PCA9685::DeviceAddress device_address;
extern const size_t output_enable_pin; extern const PCA9685::Pin output_enable_pin;
extern const long baud; extern const long baud;
extern const size_t loop_delay; extern const size_t loop_delay;
extern const uint16_t frequency; extern const PCA9685::Frequency frequency;
extern const uint16_t time_increment; extern const PCA9685::Time time_increment;
extern const double epsilon; extern const PCA9685::Percent epsilon;
} }
#endif #endif

View File

@@ -7,25 +7,25 @@
PCA9685 pca9685; PCA9685 pca9685;
uint16_t time_min; PCA9685::Time time_min;
uint16_t time_max; PCA9685::Time time_max;
uint8_t channel; PCA9685::Channel channel;
uint16_t on_time_set; PCA9685::Time on_time_set;
uint16_t off_time_set; PCA9685::Time off_time_set;
uint16_t on_time_get; PCA9685::Time on_time_get;
uint16_t off_time_get; PCA9685::Time off_time_get;
uint16_t pulse_width_set; PCA9685::Duration pulse_width_set;
uint16_t phase_shift_set; PCA9685::Duration phase_shift_set;
uint16_t pulse_width_get; PCA9685::Duration pulse_width_get;
uint16_t phase_shift_get; PCA9685::Duration phase_shift_get;
double duty_cycle_set; PCA9685::Percent duty_cycle_set;
double percent_delay_set; PCA9685::Percent percent_delay_set;
double duty_cycle_get; PCA9685::Percent duty_cycle_get;
double percent_delay_get; PCA9685::Percent percent_delay_get;
void setup() void setup()
{ {
@@ -67,7 +67,7 @@ void loop()
on_time_set = time_min; on_time_set = time_min;
off_time_set = time_max; off_time_set = time_max;
} }
for (uint8_t channel=0; channel < pca9685.getChannelCount(); ++channel) for (PCA9685::Channel channel=0; channel < pca9685.getChannelCount(); ++channel)
{ {
Serial << "frequency: " << pca9685.getFrequency() << "\n"; Serial << "frequency: " << pca9685.getFrequency() << "\n";
Serial << "channel: " << channel << ", on_time_set: " << on_time_set << ", off_time_set: " << off_time_set << "\n"; Serial << "channel: " << channel << ", on_time_set: " << on_time_set << ", off_time_set: " << off_time_set << "\n";

View File

@@ -1,7 +1,7 @@
name=PCA9685 name=PCA9685
version=2.1.4 version=3.0.2
author=Peter Polidoro <peterpolidoro@gmail.com> author=Peter Polidoro <peter@polidoro.io>
maintainer=Peter Polidoro <peterpolidoro@gmail.com> maintainer=Peter Polidoro <peter@polidoro.io>
sentence=PCA9685 16-channel 12-bit PWM controller. sentence=PCA9685 16-channel 12-bit PWM controller.
paragraph=Like this project? Please star it on GitHub! paragraph=Like this project? Please star it on GitHub!
category=Device Control category=Device Control

View File

@@ -2,7 +2,7 @@
// PCA9685.h // PCA9685.h
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef PCA9685_H #ifndef PCA9685_H
#define PCA9685_H #define PCA9685_H
@@ -15,80 +15,91 @@ class PCA9685
public: public:
PCA9685(); PCA9685();
const static uint8_t CHANNELS_PER_DEVICE = 16; typedef uint16_t Channel;
typedef uint8_t ChannelCount;
typedef uint8_t DeviceAddress;
typedef uint8_t DeviceIndex;
typedef size_t Pin;
typedef uint16_t Frequency;
typedef double Percent;
typedef uint16_t Time;
typedef uint16_t Duration;
typedef uint16_t DurationMicroseconds;
const static Channel CHANNELS_PER_DEVICE = 16;
enum {DEVICE_COUNT_MAX=55}; enum {DEVICE_COUNT_MAX=55};
// Convenience method when using a single device // Convenience method when using a single device
void setupSingleDevice(TwoWire & wire=Wire, void setupSingleDevice(TwoWire & wire=Wire,
uint8_t device_address=0x40, DeviceAddress device_address=0x40,
bool fast_mode_plus=false); bool fast_mode_plus=false);
// Methods for using a single device or multiple devices // Methods for using a single device or multiple devices
void setupOutputEnablePin(size_t output_enable_pin); void setupOutputEnablePin(Pin output_enable_pin);
void enableOutputs(size_t output_enable_pin); void enableOutputs(Pin output_enable_pin);
void disableOutputs(size_t output_enable_pin); void disableOutputs(Pin output_enable_pin);
uint16_t getFrequencyMin(); Frequency getFrequencyMin();
uint16_t getFrequencyMax(); Frequency getFrequencyMax();
void setToFrequency(uint16_t frequency); void setToFrequency(Frequency frequency);
uint16_t getFrequency(); Frequency getFrequency();
void setToServoFrequency(); void setToServoFrequency();
uint16_t getServoFrequency(); Frequency getServoFrequency();
uint8_t getChannelCount(); ChannelCount getChannelCount();
double getDutyCycleMin(); Percent getDutyCycleMin();
double getDutyCycleMax(); Percent getDutyCycleMax();
double getPercentDelayMin(); Percent getPercentDelayMin();
double getPercentDelayMax(); Percent getPercentDelayMax();
void setChannelDutyCycle(uint8_t channel, void setChannelDutyCycle(Channel channel,
double duty_cycle, Percent duty_cycle,
double percent_delay=0); Percent percent_delay=0);
void getChannelDutyCycle(uint8_t channel, void getChannelDutyCycle(Channel channel,
double & duty_cycle, Percent & duty_cycle,
double & percent_delay); Percent & percent_delay);
void setAllChannelsDutyCycle(double duty_cycle, void setAllChannelsDutyCycle(Percent duty_cycle,
double percent_delay=0); Percent percent_delay=0);
uint16_t getPulseWidthMin(); Duration getPulseWidthMin();
uint16_t getPulseWidthMax(); Duration getPulseWidthMax();
uint16_t getPhaseShiftMin(); Time getPhaseShiftMin();
uint16_t getPhaseShiftMax(); Time getPhaseShiftMax();
void setChannelPulseWidth(uint8_t channel, void setChannelPulseWidth(Channel channel,
uint16_t pulse_width, Duration pulse_width,
uint16_t phase_shift=0); Duration phase_shift=0);
void getChannelPulseWidth(uint8_t channel, void getChannelPulseWidth(Channel channel,
uint16_t & pulse_width, Duration & pulse_width,
uint16_t & phase_shift); Time & phase_shift);
void setAllChannelsPulseWidth(uint16_t pulse_width, void setAllChannelsPulseWidth(Duration pulse_width,
uint16_t phase_shift=0); Duration phase_shift=0);
void setChannelServoPulseDuration(uint8_t channel, void setChannelServoPulseDuration(Channel channel,
uint16_t pulse_duration_microseconds); DurationMicroseconds pulse_duration_microseconds);
void getChannelServoPulseDuration(uint8_t channel, void getChannelServoPulseDuration(Channel channel,
uint16_t & pulse_duration_microseconds); DurationMicroseconds & pulse_duration_microseconds);
void setAllChannelsServoPulseDuration(uint16_t pulse_duration_microseconds); void setAllChannelsServoPulseDuration(DurationMicroseconds pulse_duration_microseconds);
uint16_t getTimeMin(); Time getTimeMin();
uint16_t getTimeMax(); Time getTimeMax();
void setChannelOnAndOffTime(uint8_t channel, void setChannelOnAndOffTime(Channel channel,
uint16_t on_time, Time on_time,
uint16_t off_time); Time off_time);
void getChannelOnAndOffTime(uint8_t channel, void getChannelOnAndOffTime(Channel channel,
uint16_t & on_time, Time & on_time,
uint16_t & off_time); Time & off_time);
void setAllChannelsOnAndOffTime(uint16_t on_time, void setAllChannelsOnAndOffTime(Time on_time,
uint16_t off_time); Time off_time);
void setChannelOnTime(uint8_t channel, void setChannelOnTime(Channel channel,
uint16_t on_time); Time on_time);
void getChannelOnTime(uint8_t channel, void getChannelOnTime(Channel channel,
uint16_t & on_time); Time & on_time);
void setAllChannelsOnTime(uint16_t on_time); void setAllChannelsOnTime(Time on_time);
void setChannelOffTime(uint8_t channel, void setChannelOffTime(Channel channel,
uint16_t off_time); Time off_time);
void getChannelOffTime(uint8_t channel, void getChannelOffTime(Channel channel,
uint16_t & off_time); Time & off_time);
void setAllChannelsOffTime(uint16_t off_time); void setAllChannelsOffTime(Time off_time);
void setOutputsInverted(); void setOutputsInverted();
void setOutputsNotInverted(); void setOutputsNotInverted();
@@ -106,93 +117,93 @@ public:
// device_address=0x40 when all device address // device_address=0x40 when all device address
// hardware select lines are low // hardware select lines are low
// cannot use reserved addresses // cannot use reserved addresses
void addDevice(uint8_t device_address); void addDevice(DeviceAddress device_address);
void resetAllDevices(); void resetAllDevices();
void addDeviceToGroup0(uint8_t device_address); void addDeviceToGroup0(DeviceAddress device_address);
void removeDeviceFromGroup0(uint8_t device_address); void removeDeviceFromGroup0(DeviceAddress device_address);
void addDeviceToGroup1(uint8_t device_address); void addDeviceToGroup1(DeviceAddress device_address);
void removeDeviceFromGroup1(uint8_t device_address); void removeDeviceFromGroup1(DeviceAddress device_address);
void addDeviceToGroup2(uint8_t device_address); void addDeviceToGroup2(DeviceAddress device_address);
void removeDeviceFromGroup2(uint8_t device_address); void removeDeviceFromGroup2(DeviceAddress device_address);
void setSingleDeviceToFrequency(uint8_t device_address, void setSingleDeviceToFrequency(DeviceAddress device_address,
uint16_t frequency); Frequency frequency);
uint16_t getSingleDeviceFrequency(uint8_t device_address); Frequency getSingleDeviceFrequency(DeviceAddress device_address);
void setAllDevicesToFrequency(uint16_t frequency); void setAllDevicesToFrequency(Frequency frequency);
void setSingleDeviceToServoFrequency(uint8_t device_address); void setSingleDeviceToServoFrequency(DeviceAddress device_address);
uint16_t getSingleDeviceServoFrequency(uint8_t device_address); Frequency getSingleDeviceServoFrequency(DeviceAddress device_address);
void setAllDevicesToServoFrequency(); void setAllDevicesToServoFrequency();
uint8_t getDeviceChannelCount(); ChannelCount getDeviceChannelCount();
// Use these device address to set more than one device at a time // Use these device address to set more than one device at a time
// with the methods below // with the methods below
const static uint8_t DEVICE_ADDRESS_ALL = 0x70; const static DeviceAddress DEVICE_ADDRESS_ALL = 0x70;
const static uint8_t DEVICE_ADDRESS_GROUP0 = 0x71; const static DeviceAddress DEVICE_ADDRESS_GROUP0 = 0x71;
const static uint8_t DEVICE_ADDRESS_GROUP1 = 0x72; const static DeviceAddress DEVICE_ADDRESS_GROUP1 = 0x72;
const static uint8_t DEVICE_ADDRESS_GROUP2 = 0x73; const static DeviceAddress DEVICE_ADDRESS_GROUP2 = 0x73;
void setDeviceChannelDutyCycle(uint8_t device_address, void setDeviceChannelDutyCycle(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
double duty_cycle, Percent duty_cycle,
double percent_delay=0); Percent percent_delay=0);
void setAllDeviceChannelsDutyCycle(uint8_t device_address, void setAllDeviceChannelsDutyCycle(DeviceAddress device_address,
double duty_cycle, Percent duty_cycle,
double percent_delay=0); Percent percent_delay=0);
void setDeviceChannelPulseWidth(uint8_t device_address, void setDeviceChannelPulseWidth(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t pulse_width, Duration pulse_width,
uint16_t phase_shift=0); Duration phase_shift=0);
void setAllDeviceChannelsPulseWidth(uint8_t device_address, void setAllDeviceChannelsPulseWidth(DeviceAddress device_address,
uint16_t pulse_width, Duration pulse_width,
uint16_t phase_shift=0); Duration phase_shift=0);
void setDeviceChannelServoPulseDuration(uint8_t device_address, void setDeviceChannelServoPulseDuration(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t pulse_duration_microseconds); DurationMicroseconds pulse_duration_microseconds);
void setAllDeviceChannelsServoPulseDuration(uint8_t device_address, void setAllDeviceChannelsServoPulseDuration(DeviceAddress device_address,
uint16_t pulse_duration_microseconds); DurationMicroseconds pulse_duration_microseconds);
void setDeviceChannelOnAndOffTime(uint8_t device_address, void setDeviceChannelOnAndOffTime(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t on_time, Time on_time,
uint16_t off_time); Time off_time);
void setAllDeviceChannelsOnAndOffTime(uint8_t device_address, void setAllDeviceChannelsOnAndOffTime(DeviceAddress device_address,
uint16_t on_time, Time on_time,
uint16_t off_time); Time off_time);
void setDeviceChannelOnTime(uint8_t device_address, void setDeviceChannelOnTime(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t on_time); Time on_time);
void setAllDeviceChannelsOnTime(uint8_t device_address, void setAllDeviceChannelsOnTime(DeviceAddress device_address,
uint16_t on_time); Time on_time);
void setDeviceChannelOffTime(uint8_t device_address, void setDeviceChannelOffTime(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t off_time); Time off_time);
void setAllDeviceChannelsOffTime(uint8_t device_address, void setAllDeviceChannelsOffTime(DeviceAddress device_address,
uint16_t off_time); Time off_time);
void setSingleDeviceOutputsInverted(uint8_t device_address); void setSingleDeviceOutputsInverted(DeviceAddress device_address);
void setAllDevicesOutputsInverted(); void setAllDevicesOutputsInverted();
void setSingleDeviceOutputsNotInverted(uint8_t device_address); void setSingleDeviceOutputsNotInverted(DeviceAddress device_address);
void setAllDevicesOutputsNotInverted(); void setAllDevicesOutputsNotInverted();
void setSingleDeviceOutputsToTotemPole(uint8_t device_address); void setSingleDeviceOutputsToTotemPole(DeviceAddress device_address);
void setAllDevicesOutputsToTotemPole(); void setAllDevicesOutputsToTotemPole();
void setSingleDeviceOutputsToOpenDrain(uint8_t device_address); void setSingleDeviceOutputsToOpenDrain(DeviceAddress device_address);
void setAllDevicesOutputsToOpenDrain(); void setAllDevicesOutputsToOpenDrain();
void setSingleDeviceOutputsLowWhenDisabled(uint8_t device_address); void setSingleDeviceOutputsLowWhenDisabled(DeviceAddress device_address);
void setAllDevicesOutputsLowWhenDisabled(); void setAllDevicesOutputsLowWhenDisabled();
void setSingleDeviceOutputsHighWhenDisabled(uint8_t device_address); void setSingleDeviceOutputsHighWhenDisabled(DeviceAddress device_address);
void setAllDevicesOutputsHighWhenDisabled(); void setAllDevicesOutputsHighWhenDisabled();
void setSingleDeviceOutputsHighImpedanceWhenDisabled(uint8_t device_address); void setSingleDeviceOutputsHighImpedanceWhenDisabled(DeviceAddress device_address);
void setAllDevicesOutputsHighImpedanceWhenDisabled(); void setAllDevicesOutputsHighImpedanceWhenDisabled();
private: private:
const static uint8_t DEVICE_ADDRESS_MIN = 0x40; const static DeviceAddress DEVICE_ADDRESS_MIN = 0x40;
const static uint8_t DEVICE_ADDRESS_MAX = 0x7B; const static DeviceAddress DEVICE_ADDRESS_MAX = 0x7B;
uint8_t device_count_; uint8_t device_count_;
uint8_t device_addresses_[DEVICE_COUNT_MAX]; DeviceAddress device_addresses_[DEVICE_COUNT_MAX];
TwoWire * wire_ptr_; TwoWire * wire_ptr_;
const static long FAST_MODE_PLUS_CLOCK_FREQUENCY = 1000000; const static long FAST_MODE_PLUS_CLOCK_FREQUENCY = 1000000;
@@ -204,21 +215,21 @@ private:
const static int DEVICE_INDEX_GROUP0 = -3; const static int DEVICE_INDEX_GROUP0 = -3;
const static int DEVICE_INDEX_GROUP1 = -4; const static int DEVICE_INDEX_GROUP1 = -4;
const static int DEVICE_INDEX_GROUP2 = -5; const static int DEVICE_INDEX_GROUP2 = -5;
int deviceAddressToDeviceIndex(uint8_t device_address); int deviceAddressToDeviceIndex(DeviceAddress device_address);
const static uint8_t GENERAL_CALL_DEVICE_ADDRESS = 0x00; const static DeviceAddress GENERAL_CALL_DEVICE_ADDRESS = 0x00;
const static uint8_t SWRST = 0b110; const static uint8_t SWRST = 0b110;
// Can write to one or more device at a time // Can write to one or more device at a time
// so use address rather than index // so use address rather than index
template<typename T> template<typename T>
void write(uint8_t device_address, void write(DeviceAddress device_address,
uint8_t register_address, uint8_t register_address,
T data); T data);
// Can only read from one device at a time // Can only read from one device at a time
// so use index rather than address // so use index rather than address
template<typename T> template<typename T>
void read(uint8_t device_index, void read(DeviceIndex device_index,
uint8_t register_address, uint8_t register_address,
T & data); T & data);
@@ -238,7 +249,7 @@ private:
} fields; } fields;
uint8_t data; uint8_t data;
}; };
Mode1Register readMode1Register(uint8_t device_index); Mode1Register readMode1Register(DeviceIndex device_index);
const static uint8_t MODE2_REGISTER_ADDRESS = 0x01; const static uint8_t MODE2_REGISTER_ADDRESS = 0x01;
union Mode2Register union Mode2Register
@@ -253,54 +264,54 @@ private:
} fields; } fields;
uint8_t data; uint8_t data;
}; };
Mode2Register readMode2Register(uint8_t device_index); Mode2Register readMode2Register(DeviceIndex device_index);
void sleep(uint8_t device_index); void sleep(DeviceIndex device_index);
void wake(uint8_t device_index); void wake(DeviceIndex device_index);
void wakeAll(); void wakeAll();
void setPrescale(uint8_t device_index, void setPrescale(DeviceIndex device_index,
uint8_t prescale); uint8_t prescale);
void getPrescale(uint8_t device_index, void getPrescale(DeviceIndex device_index,
uint8_t & prescale); uint8_t & prescale);
uint8_t frequencyToPrescale(uint16_t frequency); uint8_t frequencyToPrescale(Frequency frequency);
uint16_t prescaleToFrequency(uint8_t prescale); Frequency prescaleToFrequency(uint8_t prescale);
uint8_t channelToDeviceIndex(uint8_t channel); uint8_t channelToDeviceIndex(Channel channel);
uint8_t channelToDeviceChannel(uint8_t channel); Channel channelToDeviceChannel(Channel channel);
void dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(double duty_cycle, void dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(Percent duty_cycle,
double percent_delay, Percent percent_delay,
uint16_t & pulse_width, Duration & pulse_width,
uint16_t & phase_shift); Time & phase_shift);
void pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(uint16_t pulse_width, void pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(Duration pulse_width,
uint16_t phase_shift, Duration phase_shift,
double & duty_cycle, Percent & duty_cycle,
double & percent_delay); Percent & percent_delay);
void pulseWidthAndPhaseShiftToOnTimeAndOffTime(uint16_t pulse_width, void pulseWidthAndPhaseShiftToOnTimeAndOffTime(Duration pulse_width,
uint16_t phase_shift, Duration phase_shift,
uint16_t & on_time, Time & on_time,
uint16_t & off_time); Time & off_time);
void onTimeAndOffTimeToPulseWidthAndPhaseShift(uint16_t on_time, void onTimeAndOffTimeToPulseWidthAndPhaseShift(Time on_time,
uint16_t off_time, Time off_time,
uint16_t & pulse_width, Duration & pulse_width,
uint16_t & phase_shift); Time & phase_shift);
void servoPulseDurationToPulseWidthAndPhaseShift(uint16_t pulse_duration_microseconds, void servoPulseDurationToPulseWidthAndPhaseShift(DurationMicroseconds pulse_duration_microseconds,
uint16_t & pulse_width, Duration & pulse_width,
uint16_t & phase_shift); Time & phase_shift);
void pulseWidthAndPhaseShiftToServoPulseDuration(uint16_t pulse_width, void pulseWidthAndPhaseShiftToServoPulseDuration(Duration pulse_width,
uint16_t phase_shift, Duration phase_shift,
uint16_t & pulse_duration_microseconds); DurationMicroseconds & pulse_duration_microseconds);
void setOutputsInverted(uint8_t device_index); void setOutputsInverted(DeviceIndex device_index);
void setOutputsNotInverted(uint8_t device_index); void setOutputsNotInverted(DeviceIndex device_index);
void setOutputsToTotemPole(uint8_t device_index); void setOutputsToTotemPole(DeviceIndex device_index);
void setOutputsToOpenDrain(uint8_t device_index); void setOutputsToOpenDrain(DeviceIndex device_index);
void setOutputsLowWhenDisabled(uint8_t device_index); void setOutputsLowWhenDisabled(DeviceIndex device_index);
void setOutputsHighWhenDisabled(uint8_t device_index); void setOutputsHighWhenDisabled(DeviceIndex device_index);
void setOutputsHighImpedanceWhenDisabled(uint8_t device_index); void setOutputsHighImpedanceWhenDisabled(DeviceIndex device_index);
const static uint8_t DOES_NOT_RESPOND = 0; const static uint8_t DOES_NOT_RESPOND = 0;
const static uint8_t DOES_RESPOND = 1; const static uint8_t DOES_RESPOND = 1;
@@ -325,10 +336,10 @@ private:
// Use period instead of frequency to calculate prescale since it is linear // Use period instead of frequency to calculate prescale since it is linear
// Measured 1620 Hz at prescale value 0x03, 1E6/1620=617 // Measured 1620 Hz at prescale value 0x03, 1E6/1620=617
// Datasheet says it should be 1526 Hz, 1E6/1526=655 // Datasheet says it should be 1526 Hz, 1E6/1526=655
const static uint16_t PWM_PERIOD_MIN_US = 617; const static DurationMicroseconds PWM_PERIOD_MIN_US = 617;
// Measured 25.3 Hz at prescale value 0xFF, 1E6/25.3=39525 // Measured 25.3 Hz at prescale value 0xFF, 1E6/25.3=39525
// Datasheet says it should be 24 Hz, 1E6/24=41666 // Datasheet says it should be 24 Hz, 1E6/24=41666
const static uint16_t PWM_PERIOD_MAX_US = 39525; const static DurationMicroseconds PWM_PERIOD_MAX_US = 39525;
const static uint32_t MICROSECONDS_PER_SECOND = 1000000; const static uint32_t MICROSECONDS_PER_SECOND = 1000000;
const static uint8_t OUTPUTS_INVERTED = 1; const static uint8_t OUTPUTS_INVERTED = 1;
@@ -347,14 +358,14 @@ private:
const static uint8_t RESTART_DISABLED = 0; const static uint8_t RESTART_DISABLED = 0;
const static uint8_t RESTART_CLEAR = 1; const static uint8_t RESTART_CLEAR = 1;
const static uint16_t TIME_MIN = 0; const static Time TIME_MIN = 0;
const static uint16_t TIME_MAX = 4096; const static Time TIME_MAX = 4096;
const static uint8_t PERCENT_MIN = 0; const static uint8_t PERCENT_MIN = 0;
const static uint8_t PERCENT_MAX = 100; const static uint8_t PERCENT_MAX = 100;
const static uint16_t SERVO_FREQUENCY = 50; const static Frequency SERVO_FREQUENCY = 50;
const static uint16_t SERVO_PERIOD_MICROSECONDS = 20000; const static DurationMicroseconds SERVO_PERIOD_MICROSECONDS = 20000;
}; };

View File

@@ -2,7 +2,7 @@
// PCA9685.cpp // PCA9685.cpp
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "PCA9685.h" #include "PCA9685.h"
@@ -10,14 +10,14 @@
PCA9685::PCA9685() PCA9685::PCA9685()
{ {
device_count_ = 0; device_count_ = 0;
for (uint8_t device_index=0; device_index<DEVICE_COUNT_MAX; ++device_index) for (DeviceIndex device_index=0; device_index<DEVICE_COUNT_MAX; ++device_index)
{ {
device_addresses_[device_index] = GENERAL_CALL_DEVICE_ADDRESS; device_addresses_[device_index] = GENERAL_CALL_DEVICE_ADDRESS;
} }
} }
void PCA9685::setupSingleDevice(TwoWire & wire, void PCA9685::setupSingleDevice(TwoWire & wire,
uint8_t device_address, DeviceAddress device_address,
bool fast_mode_plus) bool fast_mode_plus)
{ {
setWire(Wire,fast_mode_plus); setWire(Wire,fast_mode_plus);
@@ -25,40 +25,40 @@ void PCA9685::setupSingleDevice(TwoWire & wire,
resetAllDevices(); resetAllDevices();
} }
void PCA9685::setupOutputEnablePin(size_t output_enable_pin) void PCA9685::setupOutputEnablePin(Pin output_enable_pin)
{ {
pinMode(output_enable_pin,OUTPUT); pinMode(output_enable_pin,OUTPUT);
digitalWrite(output_enable_pin,HIGH); digitalWrite(output_enable_pin,HIGH);
} }
void PCA9685::enableOutputs(size_t output_enable_pin) void PCA9685::enableOutputs(Pin output_enable_pin)
{ {
digitalWrite(output_enable_pin,LOW); digitalWrite(output_enable_pin,LOW);
} }
void PCA9685::disableOutputs(size_t output_enable_pin) void PCA9685::disableOutputs(Pin output_enable_pin)
{ {
digitalWrite(output_enable_pin,HIGH); digitalWrite(output_enable_pin,HIGH);
} }
uint16_t PCA9685::getFrequencyMin() PCA9685::Frequency PCA9685::getFrequencyMin()
{ {
return MICROSECONDS_PER_SECOND / PWM_PERIOD_MAX_US; return MICROSECONDS_PER_SECOND / PWM_PERIOD_MAX_US;
} }
uint16_t PCA9685::getFrequencyMax() PCA9685::Frequency PCA9685::getFrequencyMax()
{ {
return MICROSECONDS_PER_SECOND / PWM_PERIOD_MIN_US; return MICROSECONDS_PER_SECOND / PWM_PERIOD_MIN_US;
} }
void PCA9685::setToFrequency(uint16_t frequency) void PCA9685::setToFrequency(Frequency frequency)
{ {
setAllDevicesToFrequency(frequency); setAllDevicesToFrequency(frequency);
} }
uint16_t PCA9685::getFrequency() PCA9685::Frequency PCA9685::getFrequency()
{ {
uint16_t frequency = 0; Frequency frequency = 0;
if (device_count_ > 0) if (device_count_ > 0)
{ {
frequency = getSingleDeviceFrequency(device_addresses_[0]); frequency = getSingleDeviceFrequency(device_addresses_[0]);
@@ -71,166 +71,166 @@ void PCA9685::setToServoFrequency()
setAllDevicesToServoFrequency(); setAllDevicesToServoFrequency();
} }
uint16_t PCA9685::getServoFrequency() PCA9685::Frequency PCA9685::getServoFrequency()
{ {
return SERVO_FREQUENCY; return SERVO_FREQUENCY;
} }
uint8_t PCA9685::getChannelCount() PCA9685::ChannelCount PCA9685::getChannelCount()
{ {
return CHANNELS_PER_DEVICE * device_count_; return CHANNELS_PER_DEVICE * device_count_;
} }
double PCA9685::getDutyCycleMin() PCA9685::Percent PCA9685::getDutyCycleMin()
{ {
return PERCENT_MIN; return PERCENT_MIN;
} }
double PCA9685::getDutyCycleMax() PCA9685::Percent PCA9685::getDutyCycleMax()
{ {
return PERCENT_MAX; return PERCENT_MAX;
} }
double PCA9685::getPercentDelayMin() PCA9685::Percent PCA9685::getPercentDelayMin()
{ {
return PERCENT_MIN; return PERCENT_MIN;
} }
double PCA9685::getPercentDelayMax() PCA9685::Percent PCA9685::getPercentDelayMax()
{ {
return PERCENT_MAX; return PERCENT_MAX;
} }
void PCA9685::setChannelDutyCycle(uint8_t channel, void PCA9685::setChannelDutyCycle(Channel channel,
double duty_cycle, Percent duty_cycle,
double percent_delay) Percent percent_delay)
{ {
uint16_t pulse_width; Duration pulse_width;
uint16_t phase_shift; Duration phase_shift;
dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(duty_cycle,percent_delay,pulse_width,phase_shift); dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(duty_cycle,percent_delay,pulse_width,phase_shift);
setChannelPulseWidth(channel,pulse_width,phase_shift); setChannelPulseWidth(channel,pulse_width,phase_shift);
} }
void PCA9685::getChannelDutyCycle(uint8_t channel, void PCA9685::getChannelDutyCycle(Channel channel,
double & duty_cycle, Percent & duty_cycle,
double & percent_delay) Percent & percent_delay)
{ {
uint16_t pulse_width; Duration pulse_width;
uint16_t phase_shift; Duration phase_shift;
getChannelPulseWidth(channel,pulse_width,phase_shift); getChannelPulseWidth(channel,pulse_width,phase_shift);
pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(pulse_width,phase_shift,duty_cycle,percent_delay); pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(pulse_width,phase_shift,duty_cycle,percent_delay);
} }
void PCA9685::setAllChannelsDutyCycle(double duty_cycle, void PCA9685::setAllChannelsDutyCycle(Percent duty_cycle,
double percent_delay) Percent percent_delay)
{ {
setAllDeviceChannelsDutyCycle(DEVICE_ADDRESS_ALL,duty_cycle,percent_delay); setAllDeviceChannelsDutyCycle(DEVICE_ADDRESS_ALL,duty_cycle,percent_delay);
} }
uint16_t PCA9685::getPulseWidthMin() PCA9685::Duration PCA9685::getPulseWidthMin()
{ {
return TIME_MIN; return TIME_MIN;
} }
uint16_t PCA9685::getPulseWidthMax() PCA9685::Duration PCA9685::getPulseWidthMax()
{ {
return TIME_MAX; return TIME_MAX;
} }
uint16_t PCA9685::getPhaseShiftMin() PCA9685::Duration PCA9685::getPhaseShiftMin()
{ {
return TIME_MIN; return TIME_MIN;
} }
uint16_t PCA9685::getPhaseShiftMax() PCA9685::Duration PCA9685::getPhaseShiftMax()
{ {
return 0xFFFF; return 0xFFFF;
} }
void PCA9685::setChannelPulseWidth(uint8_t channel, void PCA9685::setChannelPulseWidth(Channel channel,
uint16_t pulse_width, Duration pulse_width,
uint16_t phase_shift) Duration phase_shift)
{ {
uint16_t on_time; Time on_time;
uint16_t off_time; Time off_time;
pulseWidthAndPhaseShiftToOnTimeAndOffTime(pulse_width,phase_shift,on_time,off_time); pulseWidthAndPhaseShiftToOnTimeAndOffTime(pulse_width,phase_shift,on_time,off_time);
setChannelOnAndOffTime(channel,on_time,off_time); setChannelOnAndOffTime(channel,on_time,off_time);
} }
void PCA9685::getChannelPulseWidth(uint8_t channel, void PCA9685::getChannelPulseWidth(Channel channel,
uint16_t & pulse_width, Duration & pulse_width,
uint16_t & phase_shift) Duration & phase_shift)
{ {
uint16_t on_time = 0; Time on_time = 0;
uint16_t off_time = 0; Time off_time = 0;
getChannelOnAndOffTime(channel,on_time,off_time); getChannelOnAndOffTime(channel,on_time,off_time);
onTimeAndOffTimeToPulseWidthAndPhaseShift(on_time,off_time,pulse_width,phase_shift); onTimeAndOffTimeToPulseWidthAndPhaseShift(on_time,off_time,pulse_width,phase_shift);
} }
void PCA9685::setAllChannelsPulseWidth(uint16_t pulse_width, void PCA9685::setAllChannelsPulseWidth(Duration pulse_width,
uint16_t phase_shift) Duration phase_shift)
{ {
setAllDeviceChannelsPulseWidth(DEVICE_ADDRESS_ALL,pulse_width,phase_shift); setAllDeviceChannelsPulseWidth(DEVICE_ADDRESS_ALL,pulse_width,phase_shift);
} }
void PCA9685::setChannelServoPulseDuration(uint8_t channel, void PCA9685::setChannelServoPulseDuration(Channel channel,
uint16_t pulse_duration_microseconds) DurationMicroseconds pulse_duration_microseconds)
{ {
uint16_t pulse_width; Duration pulse_width;
uint16_t phase_shift; Duration phase_shift;
servoPulseDurationToPulseWidthAndPhaseShift(pulse_duration_microseconds,pulse_width,phase_shift); servoPulseDurationToPulseWidthAndPhaseShift(pulse_duration_microseconds,pulse_width,phase_shift);
setChannelPulseWidth(channel,pulse_width,phase_shift); setChannelPulseWidth(channel,pulse_width,phase_shift);
} }
void PCA9685::getChannelServoPulseDuration(uint8_t channel, void PCA9685::getChannelServoPulseDuration(Channel channel,
uint16_t & pulse_duration_microseconds) DurationMicroseconds & pulse_duration_microseconds)
{ {
uint16_t pulse_width; Duration pulse_width;
uint16_t phase_shift; Duration phase_shift;
getChannelPulseWidth(channel,pulse_width,phase_shift); getChannelPulseWidth(channel,pulse_width,phase_shift);
pulseWidthAndPhaseShiftToServoPulseDuration(pulse_width,phase_shift,pulse_duration_microseconds); pulseWidthAndPhaseShiftToServoPulseDuration(pulse_width,phase_shift,pulse_duration_microseconds);
} }
void PCA9685::setAllChannelsServoPulseDuration(uint16_t pulse_duration_microseconds) void PCA9685::setAllChannelsServoPulseDuration(DurationMicroseconds pulse_duration_microseconds)
{ {
setAllDeviceChannelsServoPulseDuration(DEVICE_ADDRESS_ALL,pulse_duration_microseconds); setAllDeviceChannelsServoPulseDuration(DEVICE_ADDRESS_ALL,pulse_duration_microseconds);
} }
uint16_t PCA9685::getTimeMin() PCA9685::Time PCA9685::getTimeMin()
{ {
return TIME_MIN; return TIME_MIN;
} }
uint16_t PCA9685::getTimeMax() PCA9685::Time PCA9685::getTimeMax()
{ {
return TIME_MAX; return TIME_MAX;
} }
void PCA9685::setChannelOnAndOffTime(uint8_t channel, void PCA9685::setChannelOnAndOffTime(Channel channel,
uint16_t on_time, Time on_time,
uint16_t off_time) Time off_time)
{ {
if (channel >= getChannelCount()) if (channel >= getChannelCount())
{ {
return; return;
} }
uint8_t device_index = channelToDeviceIndex(channel); DeviceIndex device_index = channelToDeviceIndex(channel);
uint8_t device_channel = channelToDeviceChannel(channel); Channel device_channel = channelToDeviceChannel(channel);
uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel; uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
uint32_t data = (off_time << BITS_PER_TWO_BYTES) | on_time; uint32_t data = (off_time << BITS_PER_TWO_BYTES) | on_time;
write(device_addresses_[device_index],register_address,data); write(device_addresses_[device_index],register_address,data);
} }
void PCA9685::getChannelOnAndOffTime(uint8_t channel, void PCA9685::getChannelOnAndOffTime(Channel channel,
uint16_t & on_time, Time & on_time,
uint16_t & off_time) Time & off_time)
{ {
if (channel >= getChannelCount()) if (channel >= getChannelCount())
{ {
return; return;
} }
uint8_t device_index = channelToDeviceIndex(channel); DeviceIndex device_index = channelToDeviceIndex(channel);
uint8_t device_channel = channelToDeviceChannel(channel); Channel device_channel = channelToDeviceChannel(channel);
uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel; uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
uint32_t data; uint32_t data;
read(device_index,register_address,data); read(device_index,register_address,data);
@@ -238,70 +238,70 @@ void PCA9685::getChannelOnAndOffTime(uint8_t channel,
off_time = (data >> BITS_PER_TWO_BYTES) & TWO_BYTE_MAX; off_time = (data >> BITS_PER_TWO_BYTES) & TWO_BYTE_MAX;
} }
void PCA9685::setAllChannelsOnAndOffTime(uint16_t on_time, void PCA9685::setAllChannelsOnAndOffTime(Time on_time,
uint16_t off_time) Time off_time)
{ {
setAllDeviceChannelsOnAndOffTime(DEVICE_ADDRESS_ALL,on_time,off_time); setAllDeviceChannelsOnAndOffTime(DEVICE_ADDRESS_ALL,on_time,off_time);
} }
void PCA9685::setChannelOnTime(uint8_t channel, void PCA9685::setChannelOnTime(Channel channel,
uint16_t on_time) Time on_time)
{ {
if (channel >= getChannelCount()) if (channel >= getChannelCount())
{ {
return; return;
} }
uint8_t device_index = channelToDeviceIndex(channel); DeviceIndex device_index = channelToDeviceIndex(channel);
uint8_t device_channel = channelToDeviceChannel(channel); Channel device_channel = channelToDeviceChannel(channel);
uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel; uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
write(device_addresses_[device_index],register_address,on_time); write(device_addresses_[device_index],register_address,on_time);
} }
void PCA9685::getChannelOnTime(uint8_t channel, void PCA9685::getChannelOnTime(Channel channel,
uint16_t & on_time) Time & on_time)
{ {
if (channel >= getChannelCount()) if (channel >= getChannelCount())
{ {
return; return;
} }
uint8_t device_index = channelToDeviceIndex(channel); DeviceIndex device_index = channelToDeviceIndex(channel);
uint8_t device_channel = channelToDeviceChannel(channel); Channel device_channel = channelToDeviceChannel(channel);
uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel; uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
read(device_index,register_address,on_time); read(device_index,register_address,on_time);
} }
void PCA9685::setAllChannelsOnTime(uint16_t on_time) void PCA9685::setAllChannelsOnTime(Time on_time)
{ {
setAllDeviceChannelsOnTime(DEVICE_ADDRESS_ALL,on_time); setAllDeviceChannelsOnTime(DEVICE_ADDRESS_ALL,on_time);
} }
void PCA9685::setChannelOffTime(uint8_t channel, void PCA9685::setChannelOffTime(Channel channel,
uint16_t off_time) Time off_time)
{ {
if (channel >= getChannelCount()) if (channel >= getChannelCount())
{ {
return; return;
} }
uint8_t device_index = channelToDeviceIndex(channel); DeviceIndex device_index = channelToDeviceIndex(channel);
uint8_t device_channel = channelToDeviceChannel(channel); Channel device_channel = channelToDeviceChannel(channel);
uint8_t register_address = LED0_OFF_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel; uint8_t register_address = LED0_OFF_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
write(device_addresses_[device_index],register_address,off_time); write(device_addresses_[device_index],register_address,off_time);
} }
void PCA9685::getChannelOffTime(uint8_t channel, void PCA9685::getChannelOffTime(Channel channel,
uint16_t & off_time) Time & off_time)
{ {
if (channel >= getChannelCount()) if (channel >= getChannelCount())
{ {
return; return;
} }
uint8_t device_index = channelToDeviceIndex(channel); DeviceIndex device_index = channelToDeviceIndex(channel);
uint8_t device_channel = channelToDeviceChannel(channel); Channel device_channel = channelToDeviceChannel(channel);
uint8_t register_address = LED0_OFF_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel; uint8_t register_address = LED0_OFF_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
read(device_index,register_address,off_time); read(device_index,register_address,off_time);
} }
void PCA9685::setAllChannelsOffTime(uint16_t off_time) void PCA9685::setAllChannelsOffTime(Time off_time)
{ {
setAllDeviceChannelsOffTime(DEVICE_ADDRESS_ALL,off_time); setAllDeviceChannelsOffTime(DEVICE_ADDRESS_ALL,off_time);
} }
@@ -353,7 +353,7 @@ void PCA9685::setWire(TwoWire & wire,
} }
void PCA9685::addDevice(uint8_t device_address) void PCA9685::addDevice(DeviceAddress device_address)
{ {
if ((device_count_ >= DEVICE_COUNT_MAX) || if ((device_count_ >= DEVICE_COUNT_MAX) ||
(device_address < DEVICE_ADDRESS_MIN) || (device_address < DEVICE_ADDRESS_MIN) ||
@@ -378,7 +378,7 @@ void PCA9685::resetAllDevices()
wakeAll(); wakeAll();
} }
void PCA9685::addDeviceToGroup0(uint8_t device_address) void PCA9685::addDeviceToGroup0(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -390,7 +390,7 @@ void PCA9685::addDeviceToGroup0(uint8_t device_address)
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data); write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
} }
void PCA9685::removeDeviceFromGroup0(uint8_t device_address) void PCA9685::removeDeviceFromGroup0(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -402,7 +402,7 @@ void PCA9685::removeDeviceFromGroup0(uint8_t device_address)
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data); write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
} }
void PCA9685::addDeviceToGroup1(uint8_t device_address) void PCA9685::addDeviceToGroup1(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -414,7 +414,7 @@ void PCA9685::addDeviceToGroup1(uint8_t device_address)
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data); write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
} }
void PCA9685::removeDeviceFromGroup1(uint8_t device_address) void PCA9685::removeDeviceFromGroup1(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -426,7 +426,7 @@ void PCA9685::removeDeviceFromGroup1(uint8_t device_address)
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data); write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
} }
void PCA9685::addDeviceToGroup2(uint8_t device_address) void PCA9685::addDeviceToGroup2(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -438,7 +438,7 @@ void PCA9685::addDeviceToGroup2(uint8_t device_address)
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data); write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
} }
void PCA9685::removeDeviceFromGroup2(uint8_t device_address) void PCA9685::removeDeviceFromGroup2(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -450,8 +450,8 @@ void PCA9685::removeDeviceFromGroup2(uint8_t device_address)
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data); write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
} }
void PCA9685::setSingleDeviceToFrequency(uint8_t device_address, void PCA9685::setSingleDeviceToFrequency(DeviceAddress device_address,
uint16_t frequency) Frequency frequency)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -462,9 +462,9 @@ void PCA9685::setSingleDeviceToFrequency(uint8_t device_address,
setPrescale(device_index,prescale); setPrescale(device_index,prescale);
} }
uint16_t PCA9685::getSingleDeviceFrequency(uint8_t device_address) PCA9685::Frequency PCA9685::getSingleDeviceFrequency(DeviceAddress device_address)
{ {
uint16_t frequency = 0; Frequency frequency = 0;
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index >= 0) if (device_index >= 0)
{ {
@@ -475,21 +475,21 @@ uint16_t PCA9685::getSingleDeviceFrequency(uint8_t device_address)
return frequency; return frequency;
} }
void PCA9685::setAllDevicesToFrequency(uint16_t frequency) void PCA9685::setAllDevicesToFrequency(Frequency frequency)
{ {
uint8_t prescale = frequencyToPrescale(frequency); uint8_t prescale = frequencyToPrescale(frequency);
for (uint8_t device_index=0; device_index<device_count_; ++device_index) for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
{ {
setPrescale(device_index,prescale); setPrescale(device_index,prescale);
} }
} }
void PCA9685::setSingleDeviceToServoFrequency(uint8_t device_address) void PCA9685::setSingleDeviceToServoFrequency(DeviceAddress device_address)
{ {
setSingleDeviceToFrequency(device_address,SERVO_FREQUENCY); setSingleDeviceToFrequency(device_address,SERVO_FREQUENCY);
} }
uint16_t PCA9685::getSingleDeviceServoFrequency(uint8_t device_address) PCA9685::Frequency PCA9685::getSingleDeviceServoFrequency(DeviceAddress device_address)
{ {
return SERVO_FREQUENCY; return SERVO_FREQUENCY;
} }
@@ -504,71 +504,71 @@ uint8_t PCA9685::getDeviceChannelCount()
return CHANNELS_PER_DEVICE; return CHANNELS_PER_DEVICE;
} }
void PCA9685::setDeviceChannelDutyCycle(uint8_t device_address, void PCA9685::setDeviceChannelDutyCycle(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
double duty_cycle, Percent duty_cycle,
double percent_delay) Percent percent_delay)
{ {
uint16_t pulse_width; Duration pulse_width;
uint16_t phase_shift; Duration phase_shift;
dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(duty_cycle,percent_delay,pulse_width,phase_shift); dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(duty_cycle,percent_delay,pulse_width,phase_shift);
setDeviceChannelPulseWidth(device_address,device_channel,pulse_width,phase_shift); setDeviceChannelPulseWidth(device_address,device_channel,pulse_width,phase_shift);
} }
void PCA9685::setAllDeviceChannelsDutyCycle(uint8_t device_address, void PCA9685::setAllDeviceChannelsDutyCycle(DeviceAddress device_address,
double duty_cycle, Percent duty_cycle,
double percent_delay) Percent percent_delay)
{ {
uint16_t pulse_width; Duration pulse_width;
uint16_t phase_shift; Duration phase_shift;
dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(duty_cycle,percent_delay,pulse_width,phase_shift); dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(duty_cycle,percent_delay,pulse_width,phase_shift);
setAllDeviceChannelsPulseWidth(device_address,pulse_width,phase_shift); setAllDeviceChannelsPulseWidth(device_address,pulse_width,phase_shift);
} }
void PCA9685::setDeviceChannelPulseWidth(uint8_t device_address, void PCA9685::setDeviceChannelPulseWidth(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t pulse_width, Duration pulse_width,
uint16_t phase_shift) Duration phase_shift)
{ {
uint16_t on_time; Time on_time;
uint16_t off_time; Time off_time;
pulseWidthAndPhaseShiftToOnTimeAndOffTime(pulse_width,phase_shift,on_time,off_time); pulseWidthAndPhaseShiftToOnTimeAndOffTime(pulse_width,phase_shift,on_time,off_time);
setDeviceChannelOnAndOffTime(device_address,device_channel,on_time,off_time); setDeviceChannelOnAndOffTime(device_address,device_channel,on_time,off_time);
} }
void PCA9685::setAllDeviceChannelsPulseWidth(uint8_t device_address, void PCA9685::setAllDeviceChannelsPulseWidth(DeviceAddress device_address,
uint16_t pulse_width, Duration pulse_width,
uint16_t phase_shift) Duration phase_shift)
{ {
uint16_t on_time; Time on_time;
uint16_t off_time; Time off_time;
pulseWidthAndPhaseShiftToOnTimeAndOffTime(pulse_width,phase_shift,on_time,off_time); pulseWidthAndPhaseShiftToOnTimeAndOffTime(pulse_width,phase_shift,on_time,off_time);
setAllDeviceChannelsOnAndOffTime(device_address,on_time,off_time); setAllDeviceChannelsOnAndOffTime(device_address,on_time,off_time);
} }
void PCA9685::setDeviceChannelServoPulseDuration(uint8_t device_address, void PCA9685::setDeviceChannelServoPulseDuration(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t pulse_duration_microseconds) DurationMicroseconds pulse_duration_microseconds)
{ {
uint16_t pulse_width; Duration pulse_width;
uint16_t phase_shift; Duration phase_shift;
servoPulseDurationToPulseWidthAndPhaseShift(pulse_duration_microseconds,pulse_width,phase_shift); servoPulseDurationToPulseWidthAndPhaseShift(pulse_duration_microseconds,pulse_width,phase_shift);
setDeviceChannelPulseWidth(device_address,device_channel,pulse_width,phase_shift); setDeviceChannelPulseWidth(device_address,device_channel,pulse_width,phase_shift);
} }
void PCA9685::setAllDeviceChannelsServoPulseDuration(uint8_t device_address, void PCA9685::setAllDeviceChannelsServoPulseDuration(DeviceAddress device_address,
uint16_t pulse_duration_microseconds) DurationMicroseconds pulse_duration_microseconds)
{ {
uint16_t pulse_width; Duration pulse_width;
uint16_t phase_shift; Duration phase_shift;
servoPulseDurationToPulseWidthAndPhaseShift(pulse_duration_microseconds,pulse_width,phase_shift); servoPulseDurationToPulseWidthAndPhaseShift(pulse_duration_microseconds,pulse_width,phase_shift);
setAllDeviceChannelsPulseWidth(device_address,pulse_width,phase_shift); setAllDeviceChannelsPulseWidth(device_address,pulse_width,phase_shift);
} }
void PCA9685::setDeviceChannelOnAndOffTime(uint8_t device_address, void PCA9685::setDeviceChannelOnAndOffTime(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t on_time, Time on_time,
uint16_t off_time) Time off_time)
{ {
if (device_channel >= getDeviceChannelCount()) if (device_channel >= getDeviceChannelCount())
{ {
@@ -579,18 +579,18 @@ void PCA9685::setDeviceChannelOnAndOffTime(uint8_t device_address,
write(device_address,register_address,data); write(device_address,register_address,data);
} }
void PCA9685::setAllDeviceChannelsOnAndOffTime(uint8_t device_address, void PCA9685::setAllDeviceChannelsOnAndOffTime(DeviceAddress device_address,
uint16_t on_time, Time on_time,
uint16_t off_time) Time off_time)
{ {
uint8_t register_address = ALL_LED_ON_L_REGISTER_ADDRESS; uint8_t register_address = ALL_LED_ON_L_REGISTER_ADDRESS;
uint32_t data = (off_time << BITS_PER_TWO_BYTES) | on_time; uint32_t data = (off_time << BITS_PER_TWO_BYTES) | on_time;
write(device_address,register_address,data); write(device_address,register_address,data);
} }
void PCA9685::setDeviceChannelOnTime(uint8_t device_address, void PCA9685::setDeviceChannelOnTime(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t on_time) Time on_time)
{ {
if (device_channel >= getDeviceChannelCount()) if (device_channel >= getDeviceChannelCount())
{ {
@@ -600,16 +600,16 @@ void PCA9685::setDeviceChannelOnTime(uint8_t device_address,
write(device_address,register_address,on_time); write(device_address,register_address,on_time);
} }
void PCA9685::setAllDeviceChannelsOnTime(uint8_t device_address, void PCA9685::setAllDeviceChannelsOnTime(DeviceAddress device_address,
uint16_t on_time) Time on_time)
{ {
uint8_t register_address = ALL_LED_ON_L_REGISTER_ADDRESS; uint8_t register_address = ALL_LED_ON_L_REGISTER_ADDRESS;
write(device_address,register_address,on_time); write(device_address,register_address,on_time);
} }
void PCA9685::setDeviceChannelOffTime(uint8_t device_address, void PCA9685::setDeviceChannelOffTime(DeviceAddress device_address,
uint8_t device_channel, Channel device_channel,
uint16_t off_time) Time off_time)
{ {
if (device_channel >= getDeviceChannelCount()) if (device_channel >= getDeviceChannelCount())
{ {
@@ -619,14 +619,14 @@ void PCA9685::setDeviceChannelOffTime(uint8_t device_address,
write(device_address,register_address,off_time); write(device_address,register_address,off_time);
} }
void PCA9685::setAllDeviceChannelsOffTime(uint8_t device_address, void PCA9685::setAllDeviceChannelsOffTime(DeviceAddress device_address,
uint16_t off_time) Time off_time)
{ {
uint8_t register_address = ALL_LED_OFF_L_REGISTER_ADDRESS; uint8_t register_address = ALL_LED_OFF_L_REGISTER_ADDRESS;
write(device_address,register_address,off_time); write(device_address,register_address,off_time);
} }
void PCA9685::setSingleDeviceOutputsInverted(uint8_t device_address) void PCA9685::setSingleDeviceOutputsInverted(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -638,13 +638,13 @@ void PCA9685::setSingleDeviceOutputsInverted(uint8_t device_address)
void PCA9685::setAllDevicesOutputsInverted() void PCA9685::setAllDevicesOutputsInverted()
{ {
for (uint8_t device_index=0; device_index<device_count_; ++device_index) for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
{ {
setOutputsInverted(device_index); setOutputsInverted(device_index);
} }
} }
void PCA9685::setSingleDeviceOutputsNotInverted(uint8_t device_address) void PCA9685::setSingleDeviceOutputsNotInverted(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -656,13 +656,13 @@ void PCA9685::setSingleDeviceOutputsNotInverted(uint8_t device_address)
void PCA9685::setAllDevicesOutputsNotInverted() void PCA9685::setAllDevicesOutputsNotInverted()
{ {
for (uint8_t device_index=0; device_index<device_count_; ++device_index) for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
{ {
setOutputsNotInverted(device_index); setOutputsNotInverted(device_index);
} }
} }
void PCA9685::setSingleDeviceOutputsToTotemPole(uint8_t device_address) void PCA9685::setSingleDeviceOutputsToTotemPole(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -674,13 +674,13 @@ void PCA9685::setSingleDeviceOutputsToTotemPole(uint8_t device_address)
void PCA9685::setAllDevicesOutputsToTotemPole() void PCA9685::setAllDevicesOutputsToTotemPole()
{ {
for (uint8_t device_index=0; device_index<device_count_; ++device_index) for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
{ {
setOutputsToTotemPole(device_index); setOutputsToTotemPole(device_index);
} }
} }
void PCA9685::setSingleDeviceOutputsToOpenDrain(uint8_t device_address) void PCA9685::setSingleDeviceOutputsToOpenDrain(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -692,13 +692,13 @@ void PCA9685::setSingleDeviceOutputsToOpenDrain(uint8_t device_address)
void PCA9685::setAllDevicesOutputsToOpenDrain() void PCA9685::setAllDevicesOutputsToOpenDrain()
{ {
for (uint8_t device_index=0; device_index<device_count_; ++device_index) for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
{ {
setOutputsToOpenDrain(device_index); setOutputsToOpenDrain(device_index);
} }
} }
void PCA9685::setSingleDeviceOutputsLowWhenDisabled(uint8_t device_address) void PCA9685::setSingleDeviceOutputsLowWhenDisabled(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -710,13 +710,13 @@ void PCA9685::setSingleDeviceOutputsLowWhenDisabled(uint8_t device_address)
void PCA9685::setAllDevicesOutputsLowWhenDisabled() void PCA9685::setAllDevicesOutputsLowWhenDisabled()
{ {
for (uint8_t device_index=0; device_index<device_count_; ++device_index) for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
{ {
setOutputsLowWhenDisabled(device_index); setOutputsLowWhenDisabled(device_index);
} }
} }
void PCA9685::setSingleDeviceOutputsHighWhenDisabled(uint8_t device_address) void PCA9685::setSingleDeviceOutputsHighWhenDisabled(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -728,13 +728,13 @@ void PCA9685::setSingleDeviceOutputsHighWhenDisabled(uint8_t device_address)
void PCA9685::setAllDevicesOutputsHighWhenDisabled() void PCA9685::setAllDevicesOutputsHighWhenDisabled()
{ {
for (uint8_t device_index=0; device_index<device_count_; ++device_index) for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
{ {
setOutputsHighWhenDisabled(device_index); setOutputsHighWhenDisabled(device_index);
} }
} }
void PCA9685::setSingleDeviceOutputsHighImpedanceWhenDisabled(uint8_t device_address) void PCA9685::setSingleDeviceOutputsHighImpedanceWhenDisabled(DeviceAddress device_address)
{ {
int device_index = deviceAddressToDeviceIndex(device_address); int device_index = deviceAddressToDeviceIndex(device_address);
if (device_index < 0) if (device_index < 0)
@@ -746,7 +746,7 @@ void PCA9685::setSingleDeviceOutputsHighImpedanceWhenDisabled(uint8_t device_add
void PCA9685::setAllDevicesOutputsHighImpedanceWhenDisabled() void PCA9685::setAllDevicesOutputsHighImpedanceWhenDisabled()
{ {
for (uint8_t device_index=0; device_index<device_count_; ++device_index) for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
{ {
setOutputsHighImpedanceWhenDisabled(device_index); setOutputsHighImpedanceWhenDisabled(device_index);
} }
@@ -754,7 +754,7 @@ void PCA9685::setAllDevicesOutputsHighImpedanceWhenDisabled()
// private // private
int PCA9685::deviceAddressToDeviceIndex(uint8_t device_address) int PCA9685::deviceAddressToDeviceIndex(DeviceAddress device_address)
{ {
int device_index = DEVICE_INDEX_NONE; int device_index = DEVICE_INDEX_NONE;
if (device_address == DEVICE_ADDRESS_ALL) if (device_address == DEVICE_ADDRESS_ALL)
@@ -787,28 +787,28 @@ int PCA9685::deviceAddressToDeviceIndex(uint8_t device_address)
return device_index; return device_index;
} }
PCA9685::Mode1Register PCA9685::readMode1Register(uint8_t device_index) PCA9685::Mode1Register PCA9685::readMode1Register(DeviceIndex device_index)
{ {
Mode1Register mode1_register; Mode1Register mode1_register;
read(device_index,MODE1_REGISTER_ADDRESS,mode1_register.data); read(device_index,MODE1_REGISTER_ADDRESS,mode1_register.data);
return mode1_register; return mode1_register;
} }
PCA9685::Mode2Register PCA9685::readMode2Register(uint8_t device_index) PCA9685::Mode2Register PCA9685::readMode2Register(DeviceIndex device_index)
{ {
Mode2Register mode2_register; Mode2Register mode2_register;
read(device_index,MODE2_REGISTER_ADDRESS,mode2_register.data); read(device_index,MODE2_REGISTER_ADDRESS,mode2_register.data);
return mode2_register; return mode2_register;
} }
void PCA9685::sleep(uint8_t device_index) void PCA9685::sleep(DeviceIndex device_index)
{ {
Mode1Register mode1_register = readMode1Register(device_index); Mode1Register mode1_register = readMode1Register(device_index);
mode1_register.fields.sleep = SLEEP; mode1_register.fields.sleep = SLEEP;
write(device_addresses_[device_index],MODE1_REGISTER_ADDRESS,mode1_register.data); write(device_addresses_[device_index],MODE1_REGISTER_ADDRESS,mode1_register.data);
} }
void PCA9685::wake(uint8_t device_index) void PCA9685::wake(DeviceIndex device_index)
{ {
Mode1Register mode1_register = readMode1Register(device_index); Mode1Register mode1_register = readMode1Register(device_index);
mode1_register.fields.sleep = WAKE; mode1_register.fields.sleep = WAKE;
@@ -824,13 +824,13 @@ void PCA9685::wake(uint8_t device_index)
void PCA9685::wakeAll() void PCA9685::wakeAll()
{ {
for (uint8_t device_index=0; device_index<device_count_; ++device_index) for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
{ {
wake(device_index); wake(device_index);
} }
} }
void PCA9685::setPrescale(uint8_t device_index, void PCA9685::setPrescale(DeviceIndex device_index,
uint8_t prescale) uint8_t prescale)
{ {
sleep(device_index); sleep(device_index);
@@ -838,24 +838,24 @@ void PCA9685::setPrescale(uint8_t device_index,
wake(device_index); wake(device_index);
} }
void PCA9685::getPrescale(uint8_t device_index, void PCA9685::getPrescale(DeviceIndex device_index,
uint8_t & prescale) uint8_t & prescale)
{ {
read(device_index,PRE_SCALE_REGISTER_ADDRESS,prescale); read(device_index,PRE_SCALE_REGISTER_ADDRESS,prescale);
} }
uint8_t PCA9685::frequencyToPrescale(uint16_t frequency) uint8_t PCA9685::frequencyToPrescale(Frequency frequency)
{ {
uint16_t period_us = MICROSECONDS_PER_SECOND / frequency; DurationMicroseconds period_us = MICROSECONDS_PER_SECOND / frequency;
period_us = constrain(period_us,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US); period_us = constrain(period_us,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US);
uint8_t prescale = map(period_us,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US,PRE_SCALE_MIN,PRE_SCALE_MAX); uint8_t prescale = map(period_us,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US,PRE_SCALE_MIN,PRE_SCALE_MAX);
return prescale; return prescale;
} }
uint16_t PCA9685::prescaleToFrequency(uint8_t prescale) PCA9685::Frequency PCA9685::prescaleToFrequency(uint8_t prescale)
{ {
uint16_t frequency = 0; Frequency frequency = 0;
uint16_t period_us = map(prescale,PRE_SCALE_MIN,PRE_SCALE_MAX,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US); DurationMicroseconds period_us = map(prescale,PRE_SCALE_MIN,PRE_SCALE_MAX,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US);
if (period_us > 0) if (period_us > 0)
{ {
frequency = round((double)MICROSECONDS_PER_SECOND / (double)period_us); frequency = round((double)MICROSECONDS_PER_SECOND / (double)period_us);
@@ -863,38 +863,38 @@ uint16_t PCA9685::prescaleToFrequency(uint8_t prescale)
return frequency; return frequency;
} }
uint8_t PCA9685::channelToDeviceIndex(uint8_t channel) uint8_t PCA9685::channelToDeviceIndex(Channel channel)
{ {
return channel / CHANNELS_PER_DEVICE; return channel / CHANNELS_PER_DEVICE;
} }
uint8_t PCA9685::channelToDeviceChannel(uint8_t channel) PCA9685::Channel PCA9685::channelToDeviceChannel(Channel channel)
{ {
return channel % CHANNELS_PER_DEVICE; return channel % CHANNELS_PER_DEVICE;
} }
void PCA9685::dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(double duty_cycle, void PCA9685::dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(Percent duty_cycle,
double percent_delay, Percent percent_delay,
uint16_t & pulse_width, Duration & pulse_width,
uint16_t & phase_shift) Duration & phase_shift)
{ {
pulse_width = round(((double)TIME_MAX * duty_cycle) / (double)PERCENT_MAX); pulse_width = round(((double)TIME_MAX * duty_cycle) / (double)PERCENT_MAX);
phase_shift = round(((double)TIME_MAX * percent_delay) / (double)PERCENT_MAX); phase_shift = round(((double)TIME_MAX * percent_delay) / (double)PERCENT_MAX);
} }
void PCA9685::pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(uint16_t pulse_width, void PCA9685::pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(Duration pulse_width,
uint16_t phase_shift, Duration phase_shift,
double & duty_cycle, Percent & duty_cycle,
double & percent_delay) Percent & percent_delay)
{ {
duty_cycle = (double)(pulse_width * PERCENT_MAX) / (double)TIME_MAX; duty_cycle = (double)(pulse_width * PERCENT_MAX) / (double)TIME_MAX;
percent_delay = (double)(phase_shift * PERCENT_MAX) / (double)TIME_MAX; percent_delay = (double)(phase_shift * PERCENT_MAX) / (double)TIME_MAX;
} }
void PCA9685::pulseWidthAndPhaseShiftToOnTimeAndOffTime(uint16_t pulse_width, void PCA9685::pulseWidthAndPhaseShiftToOnTimeAndOffTime(Duration pulse_width,
uint16_t phase_shift, Duration phase_shift,
uint16_t & on_time, Time & on_time,
uint16_t & off_time) Time & off_time)
{ {
if (pulse_width == TIME_MIN) if (pulse_width == TIME_MIN)
{ {
@@ -912,10 +912,10 @@ void PCA9685::pulseWidthAndPhaseShiftToOnTimeAndOffTime(uint16_t pulse_width,
off_time = (on_time + pulse_width) % TIME_MAX; off_time = (on_time + pulse_width) % TIME_MAX;
} }
void PCA9685::onTimeAndOffTimeToPulseWidthAndPhaseShift(uint16_t on_time, void PCA9685::onTimeAndOffTimeToPulseWidthAndPhaseShift(Time on_time,
uint16_t off_time, Time off_time,
uint16_t & pulse_width, Duration & pulse_width,
uint16_t & phase_shift) Duration & phase_shift)
{ {
if (on_time == TIME_MAX) if (on_time == TIME_MAX)
{ {
@@ -939,65 +939,65 @@ void PCA9685::onTimeAndOffTimeToPulseWidthAndPhaseShift(uint16_t on_time,
phase_shift = on_time; phase_shift = on_time;
} }
void PCA9685::servoPulseDurationToPulseWidthAndPhaseShift(uint16_t pulse_duration_microseconds, void PCA9685::servoPulseDurationToPulseWidthAndPhaseShift(DurationMicroseconds pulse_duration_microseconds,
uint16_t & pulse_width, Duration & pulse_width,
uint16_t & phase_shift) Duration & phase_shift)
{ {
phase_shift = 0; phase_shift = 0;
pulse_width = (pulse_duration_microseconds * TIME_MAX) / SERVO_PERIOD_MICROSECONDS; pulse_width = (pulse_duration_microseconds * TIME_MAX) / SERVO_PERIOD_MICROSECONDS;
} }
void PCA9685::pulseWidthAndPhaseShiftToServoPulseDuration(uint16_t pulse_width, void PCA9685::pulseWidthAndPhaseShiftToServoPulseDuration(Duration pulse_width,
uint16_t phase_shift, Duration phase_shift,
uint16_t & pulse_duration_microseconds) DurationMicroseconds & pulse_duration_microseconds)
{ {
uint16_t period_us = SERVO_PERIOD_MICROSECONDS; DurationMicroseconds period_us = SERVO_PERIOD_MICROSECONDS;
pulse_duration_microseconds = (pulse_width * period_us) / TIME_MAX; pulse_duration_microseconds = (pulse_width * period_us) / TIME_MAX;
} }
void PCA9685::setOutputsInverted(uint8_t device_index) void PCA9685::setOutputsInverted(DeviceIndex device_index)
{ {
Mode2Register mode2_register = readMode2Register(device_index); Mode2Register mode2_register = readMode2Register(device_index);
mode2_register.fields.invrt = OUTPUTS_INVERTED; mode2_register.fields.invrt = OUTPUTS_INVERTED;
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data); write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
} }
void PCA9685::setOutputsNotInverted(uint8_t device_index) void PCA9685::setOutputsNotInverted(DeviceIndex device_index)
{ {
Mode2Register mode2_register = readMode2Register(device_index); Mode2Register mode2_register = readMode2Register(device_index);
mode2_register.fields.invrt = OUTPUTS_NOT_INVERTED; mode2_register.fields.invrt = OUTPUTS_NOT_INVERTED;
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data); write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
} }
void PCA9685::setOutputsToTotemPole(uint8_t device_index) void PCA9685::setOutputsToTotemPole(DeviceIndex device_index)
{ {
Mode2Register mode2_register = readMode2Register(device_index); Mode2Register mode2_register = readMode2Register(device_index);
mode2_register.fields.outdrv = OUTPUTS_TOTEM_POLE; mode2_register.fields.outdrv = OUTPUTS_TOTEM_POLE;
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data); write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
} }
void PCA9685::setOutputsToOpenDrain(uint8_t device_index) void PCA9685::setOutputsToOpenDrain(DeviceIndex device_index)
{ {
Mode2Register mode2_register = readMode2Register(device_index); Mode2Register mode2_register = readMode2Register(device_index);
mode2_register.fields.outdrv = OUTPUTS_OPEN_DRAIN; mode2_register.fields.outdrv = OUTPUTS_OPEN_DRAIN;
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data); write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
} }
void PCA9685::setOutputsLowWhenDisabled(uint8_t device_index) void PCA9685::setOutputsLowWhenDisabled(DeviceIndex device_index)
{ {
Mode2Register mode2_register = readMode2Register(device_index); Mode2Register mode2_register = readMode2Register(device_index);
mode2_register.fields.outne = OUTPUTS_LOW_WHEN_DISABLED; mode2_register.fields.outne = OUTPUTS_LOW_WHEN_DISABLED;
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data); write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
} }
void PCA9685::setOutputsHighWhenDisabled(uint8_t device_index) void PCA9685::setOutputsHighWhenDisabled(DeviceIndex device_index)
{ {
Mode2Register mode2_register = readMode2Register(device_index); Mode2Register mode2_register = readMode2Register(device_index);
mode2_register.fields.outne = OUTPUTS_HIGH_WHEN_DISABLED; mode2_register.fields.outne = OUTPUTS_HIGH_WHEN_DISABLED;
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data); write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
} }
void PCA9685::setOutputsHighImpedanceWhenDisabled(uint8_t device_index) void PCA9685::setOutputsHighImpedanceWhenDisabled(DeviceIndex device_index)
{ {
Mode2Register mode2_register = readMode2Register(device_index); Mode2Register mode2_register = readMode2Register(device_index);
mode2_register.fields.outne = OUTPUTS_HIGH_IMPEDANCE_WHEN_DISABLED; mode2_register.fields.outne = OUTPUTS_HIGH_IMPEDANCE_WHEN_DISABLED;

View File

@@ -3,29 +3,31 @@
// //
// //
// Authors: // Authors:
// Peter Polidoro peterpolidoro@gmail.com // Peter Polidoro peter@polidoro.io
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef PCA9685_DEFINITIONS_H #ifndef PCA9685_DEFINITIONS_H
#define PCA9685_DEFINITIONS_H #define PCA9685_DEFINITIONS_H
template<typename T> template<typename T>
void PCA9685::write(uint8_t device_address, void PCA9685::write(DeviceAddress device_address,
uint8_t register_address, uint8_t register_address,
T data) T data)
{ {
int byte_count = sizeof(data); int byte_count = sizeof(data);
wire_ptr_->beginTransmission(device_address); wire_ptr_->beginTransmission(device_address);
wire_ptr_->write(register_address); wire_ptr_->write(register_address);
uint8_t write_byte;
for (int byte_n=0; byte_n<byte_count; ++byte_n) for (int byte_n=0; byte_n<byte_count; ++byte_n)
{ {
wire_ptr_->write((data >> (BITS_PER_BYTE * byte_n)) & BYTE_MAX); write_byte = (data >> (BITS_PER_BYTE * byte_n)) & BYTE_MAX;
wire_ptr_->write(write_byte);
} }
wire_ptr_->endTransmission(); wire_ptr_->endTransmission();
} }
template<typename T> template<typename T>
void PCA9685::read(uint8_t device_index, void PCA9685::read(DeviceIndex device_index,
uint8_t register_address, uint8_t register_address,
T & data) T & data)
{ {

View File

@@ -0,0 +1,38 @@
#include <Wire.h>
#define lm75_addr 0b1001000
#define led_addr 0b111010
byte data;
long cast;
void setup(){
Wire.begin();
Serial.begin(115200);
}
void loop(){
Wire.requestFrom(lm75_addr, 1);
if(Wire.available() >= 1){
data = Wire.read();
Serial.print("Temp: ");
Serial.print(data);
Serial.println(" ");
Wire.beginTransmission(led_addr);
cast = map(data, 25, 43, 1, 8);
// Geht nicht
/*switch(data){
case 25: cast = 0b01111111;
}
*/
Serial.print("cast: ");
Serial.print(cast);
Serial.println(" ");
Wire.write(cast, );
Wire.endTransmission();
delay(500);
}
}

View File

@@ -0,0 +1,20 @@
const int LED_gruen = 33;
const int Taster2 = 2;
void setup() {
pinMode(LED_gruen, OUTPUT);
pinMode(Taster2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(Taster2), &Toggle, FALLING);
}
void loop() {
digitalWrite(LED_gruen, HIGH);
delay(250);
digitalWrite(LED_gruen, LOW);
delay(250);
}
void Toggle(){
digitalWrite(LED_gruen, !digitalRead(LED_gruen));
}

View File

@@ -0,0 +1,55 @@
enum zustaende_t {z0, z1, z2, z3} zustand;
const int taster2 = 2, taster4 = 4, led_rot = 32, led_gruen = 33;
bool taster2_g, taster4_g;
// Resoulution 10 Bits -> 2^10 -> 1024
void setup() {
Serial.begin(115200);
pinMode(taster2, INPUT_PULLUP);
pinMode(taster4, INPUT_PULLUP);
ledcAttach(led_rot, 50, 10);
ledcAttach(led_gruen, 50, 10);
zustand = z0;
ledcWrite(led_rot, 1024);
ledcWrite(led_gruen, 1024);
}
void loop() {
einlesen();
verarbeiten();
}
void einlesen(){
}
void verarbeiten(){
switch(zustand){
case z0:
if (digitalRead(taster2) == LOW) zustand = z1;
ledcWrite(led_gruen, 1024);
ledcWrite(led_rot, 1024);
Serial.println("z0");
break;
case z1:
if (digitalRead(taster4) == LOW) zustand = z2;
ledcWrite(led_gruen, 1024);
ledcWrite(led_rot, 0);
Serial.println("z1");
break;
case z2:
if (digitalRead(taster2) == LOW) zustand = z3;
ledcWrite(led_gruen, 0);
ledcWrite(led_rot, 1024);
Serial.println("z2");
break;
case z3:
if (digitalRead(taster4) == LOW) zustand = z0;
ledcWrite(led_gruen, 512);
ledcWrite(led_rot, 512);
Serial.println("z3");
break;
default:
break;
}
}

View File

@@ -0,0 +1,29 @@
volatile uint32_t lastTime, countWind;
uint32_t showTime;
const int windSensorPin = 2; // Pin, an dem der Windsensor angeschlossen ist
float windSpeed;
const float conversionFactor = 0.0875; // Beispiel-Umrechnungsfaktor (muss angepasst werden)
void setup() {
Serial.begin(115200);
byte intNr = digitalPinToInterrupt(windSensorPin);
attachInterrupt(intNr, windCounter, FALLING);
pinMode(windSensorPin, INPUT_PULLUP);
}
void loop() {
uint32_t currentTime = millis();
if (currentTime - showTime >= 1000) {
showTime = currentTime;
windSpeed = countWind * conversionFactor; // Windgeschwindigkeit berechnen
Serial.printf("Windgeschwindigkeit: %5.2f m/s\n", windSpeed);
countWind = 0; // Zähler zurücksetzen
}
}
void windCounter() {
if (millis() - lastTime > 10) {
countWind++;
lastTime = millis();
}
}

View File

@@ -0,0 +1,45 @@
<?php
require_once "personen-class.php";
class Lehrer extends Person{
// Attribute (Member)
private int $gehaltsstufe;#
// Klassen Arttribute
public static int $maxGehaltsstufe =16;
// spezieller (parametrisierter) Konstruktor
public function __construct(string $vn, string $nn, int $gs) {
parent::__construct($vn, $nn);
$this->setGehaltsstufe($gs);
}
// Öffentliche Zugriffsfunktionen
// Setter
public function setGehaltsstufe(int $gs): void {
$this->gehaltsstufe = $gs;
}
// Getter
public function getGehaltsstufe(): int {
return $this->gehaltsstufe;
}
// Sonstige Funktionen
public function ausgabe() { // Funktion ausgabe() der Elternklasse
// überschreibt => erweitern
parent::ausgabe();
echo "Gehaltsstufe: A$this->gehaltsstufe";
echo "</p>";
}
public function befoerdern():bool{
// self die klasse selsbst -> Klasse lehrer
// $this-> die Instanz der Klasse
if($this->gehaltsstufe < self::$maxGehaltsstufe){
$this->gehaltsstufe++;
return true;
}
return false;
}
}
?>

View File

@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<?php
ini_set("display_errors", "on");
require_once "lehrer-class.php";
require_once "schueler-class.php";
require_once "personen-class.php";
// --------------------
// L E H R E R T E S T
// --------------------
echo "<h2>Lehrer</h2>";
$l = new Lehrer("Michael", "Staudt", 13);
$l->ausgabe();
if($l->befoerdern()){
echo "<p>Beförderung erfolgreich!</p>";
echo "Neue Stufe: ".$l->getGehaltsstufe()."</p>";
}else {
echo "<p>Beförderung nicht erfolgreich, da höchste Stufe erreicht</p>";
}
// ------------------------
// S C H U E L E R T E S T
// ------------------------
echo "<h2>Schüler</h2>";
$s = new Schueler("daniel", "vici123", "2BKI1");
$s->ausgabe();
// --------------------
// P E R S O N T E S T
// --------------------
echo "<h2>Personen</h2>";
$p = new Person("danielvici", "123");
$p->ausgabe();
?>
<br>
<p>Über mir sollte php code ausgeführt werden</p>
</body>
</html>

View File

@@ -0,0 +1,5 @@
<?php
// Hab nicht mit geschrieben...
?>

View File

@@ -0,0 +1,42 @@
<?php
class Person { // dient nur zur vererberung, kein objekt erzeugen
// Attribute (Member)
private string $vorname; // # protected, + public, - private
private string $nachname; // #
// spezieller (parametrisierter) Konstruktor
public function __construct(string $vn, string $nn) {
$this->setVorname($vn);
$this->setNachname($nn);
}
// Öffentliche Zugriffsfunktionen
// Setter
public function setVorname(string $vn): void {
$this->vorname = $vn;
}
public function setNachname(string $nn): void {
$this->nachname = $nn;
}
// Getter
public function getVorname(): string {
return $this->vorname;
}
public function getNachname(): string {
return $this->nachname;
}
// Sonstige Funktionen
public function ausgabe() {
echo "<p>";
echo "Vorname: $this->vorname<br>";
echo "Nachname: $this->nachname<br>";
}
}
?>

View File

@@ -0,0 +1,39 @@
<?php
require_once "personen-class.php";
class Schueler extends Person{
// Attribute (Member)
private string $klasse;
// spezieller (parametrisierter) Konstruktor
public function __construct(string $vn, string $nn, string $kl) {
parent::__construct($vn, $nn);
$this->setKlasse($kl);
}
// Öffentliche Zugriffsfunktionen
// Setter
public function setKlasse(string $kl): void {
$this->klasse = $kl;
}
// Getter
public function getKlasse(): string {
return $this->klasse;
}
// Sonstige Funktionen
public function ausgabe() {
parent::ausgabe();
echo "Klasse: $this->klasse";
echo "</p>";
}
public function versetzen():bool{
if($this->klasse == "2BKI1"){
$this->klasse = "2BKI2";
return true;
}
return false;
}
}
?>

View File

@@ -0,0 +1,36 @@
<?php
ini_set("display_errors", "on");
class mitarbeiter {
public string $name;
public string $geburtsdatum;
public string $gehalt;
public function __construct(string $n, string $gb, string $g) {
$this->name = $n;
$this->geburtsdatum = $gb;
$this->gehalt = $g;
}
public function getInfo(): string {
echo "Name: $this->name";
echo "Geburtsdatum: $this->geburtsdatum";
echo" Gehalt: $this->gehalt";
}
public function getJahresgehalt(): string {
echo $this->gehalt * 12;
}
}
class vollzeit extends mitarbeiter {
public string $arbeitszeit =40;
public function __construct(string $n, string $gb, string $g) {
parent::__construct($n, $gb, $g);
$this->name = $n;
$this->geburtsdatum = $gb;
$this->gehalt = $g;
}
}
?>

View File

@@ -0,0 +1,14 @@
<?php
ini_set("display_errors", "on");
class teilnehmer {
public string $name;
public string $vorname;
public string $code;
public function __construct(string $n, string $vn, string $c) {
$this->name = $n;
$this->vorname = $vn;
$this->code = $c;
}
}
?>

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Teilnehmer</h1>
<?php
ini_set("display_errors", "on");
require_once 'teilnehmer.php';
require_once 'tnintern.php';
echo "<h2>Daniel</h2>";
$tl = new tnintern("vici123", "daniel", "2BKI1", "IT");
$tl->getDaten();
echo "<br>";
echo "<h2>Aurelion Sol</h2>";
$tl = new tnintern("sol", "aurelion", "mage", "midde");
$tl->getDaten();
?>
<br>
<p>Über mir sollte php code ausgeführt werden</p>
</body>
</html>

View File

@@ -0,0 +1,26 @@
<?php
require_once 'teilnehmer.php';
ini_set("display_errors", "on");
class tnintern extends teilnehmer {
private string $abteilung;
private int $anzahl=0;
public function __construct($n, $vn, $c ,$abteilung) {
parent::__construct($vn, $n, $c);
$this->abteilung = $abteilung;
$this->anzahl= $this->anzahl+1;
}
public function getDaten() {
echo "Name: $this->name <br>";
echo "Vorname: $this->vorname <br>";
echo "Code: $this->code <br>";
echo "Abteilung: $this->abteilung <br>";
echo "Anzahl: $this->anzahl";
}
public function getAnzahl():int {
return $this->anzahl;
}
}
?>