the pca9685 is not the most precise chip so tweaking with a scope is a great idea

master
Kerem Yollu 4 years ago
parent b5edea5c7f
commit 4fee0dd031

@ -7,7 +7,7 @@ Pca9685::Pca9685(i2c_ch1_pImpL* i2c, ErrorHandler* err)
errorHandling = err; errorHandling = err;
m_isExternalClock = 0; m_isExternalClock = 0;
m_oscillatorFreq = PCA9685_FREQUENCY_OSCILLATOR; m_oscillatorFreq = PCA9685_FREQUENCY_OSCILLATOR;
setPwmFreq(48); setPwmFreq(1526);
m_currentLED = PCA9685_LED_PWM_REG_START; m_currentLED = PCA9685_LED_PWM_REG_START;
errorHandling->addNewError(-1,__FILE__,"Selected duty cycle is too big",KILL); errorHandling->addNewError(-1,__FILE__,"Selected duty cycle is too big",KILL);
@ -31,7 +31,7 @@ Pca9685::Pca9685(i2c_ch1_pImpL* i2c, ErrorHandler* err)
* *
*/ */
void Pca9685::setPwmFreq(uint16_t frequency) void Pca9685::setPwmFreq(float frequency)
{ {
if(frequency > 1526) if(frequency > 1526)
{ {
@ -49,17 +49,21 @@ void Pca9685::setPwmFreq(uint16_t frequency)
errorHandling->handleError(-4,__FILE__); errorHandling->handleError(-4,__FILE__);
} }
m_currentPrescale = (m_oscillatorFreq / ( 4096 * frequency) ) -1; m_currentPrescale = round((m_oscillatorFreq / ( 4096 * frequency)) - 1);
std::cout << "Prescaler is set to: " << unsigned(m_currentPrescale) << std::endl; std::cout << unsigned(m_currentPrescale) << std::endl;
sleep(); sleep();
i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_PRESCALE, m_currentPrescale); i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_PRESCALE, m_currentPrescale);
wakeup(); wakeup();
} }
void Pca9685::setPwmMicroSeconds(uint16_t microSeconds) float Pca9685::getPwmFreq()
{ {
m_currentPrescale = i2c_pca9685->readByte(PCA9685_I2C_ADDRESS,PCA9685_REG_PRESCALE);
m_currentPwmFreq = (m_oscillatorFreq / (4096 * ((float)m_currentPrescale + 1)));
std::cout << m_currentPwmFreq << std::endl;
return m_currentPwmFreq;
} }
void Pca9685::setDutyPercent(uint8_t ledNo, uint8_t on, uint8_t off) void Pca9685::setDutyPercent(uint8_t ledNo, uint8_t on, uint8_t off)
{ {
@ -102,10 +106,6 @@ void Pca9685::setDutyRaw(uint8_t ledNo, uint16_t on, uint16_t off)
i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED + PCA9685_PWM_OFF_H_OFFSET, off >> 8); i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED + PCA9685_PWM_OFF_H_OFFSET, off >> 8);
} }
void Pca9685::setDutyMicroSecond(uint8_t ledNo, uint16_t on, uint16_t off)
{
}
void Pca9685::setOnOff(uint8_t ledNo, bool onOff, bool invert) void Pca9685::setOnOff(uint8_t ledNo, bool onOff, bool invert)
{ {
@ -161,3 +161,4 @@ void Pca9685::wakeup()
i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_MODE1, m_curMode); i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_MODE1, m_curMode);
usleep(PCA9685_OSC_STAB_TIME_US); // refer to datasheet page 14 usleep(PCA9685_OSC_STAB_TIME_US); // refer to datasheet page 14
} }

@ -57,8 +57,8 @@ class Pca9685
{ {
public: public:
Pca9685(i2c_ch1_pImpL* i2c,ErrorHandler* err); Pca9685(i2c_ch1_pImpL* i2c,ErrorHandler* err);
void setPwmFreq(uint16_t frequency); void setPwmFreq(float frequency);
void setPwmMicroSeconds(uint16_t microSeconds); float getPwmFreq();
void setDutyPercent(uint8_t ledNo, uint8_t on, uint8_t off); void setDutyPercent(uint8_t ledNo, uint8_t on, uint8_t off);
void setDutyRaw(uint8_t ledNo, uint16_t on, uint16_t off); void setDutyRaw(uint8_t ledNo, uint16_t on, uint16_t off);
void setDutyMicroSecond(uint8_t ledNo, uint16_t on, uint16_t off); void setDutyMicroSecond(uint8_t ledNo, uint16_t on, uint16_t off);
@ -71,10 +71,10 @@ class Pca9685
private: private:
uint8_t m_currentLED; uint8_t m_currentLED;
uint8_t m_curMode; uint8_t m_curMode;
uint16_t m_currentPwmFreq; float m_currentPwmFreq;
uint8_t m_currentPrescale; uint8_t m_currentPrescale;
uint8_t m_isExternalClock; uint8_t m_isExternalClock;
uint32_t m_oscillatorFreq; float m_oscillatorFreq;
ErrorHandler* errorHandling; ErrorHandler* errorHandling;
i2c_ch1_pImpL* i2c_pca9685; i2c_ch1_pImpL* i2c_pca9685;
}; };

@ -25,10 +25,15 @@ Pca9685 pwmGenarator(&i2c, &errorHandle);
int initPlatform() int initPlatform()
{ {
char Msg[6] = "hello"; char char_array[TOTAL_CHAR_CAP];
uint8_t pos = 0;
lcd_init(&i2c); lcd_init(&i2c);
lcd_display_string(1,0,Msg); strcpy(char_array, "Pwm Freq: ");
// Dev. Module initialisation "Ex i2c_init() ...." lcd_display_string(1,pos,char_array);
std::string Msg = std::to_string(pwmGenarator.getPwmFreq());
strcpy(char_array, Msg.c_str());
pos = strlen(char_array) + 1;
lcd_display_string(1,pos, char_array);
return 0; return 0;
} }

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save