diff --git a/developpment/drivers/ads1015/ads1050.cpp b/developpment/drivers/ads1015/ads1050.cpp new file mode 100644 index 0000000..e69de29 diff --git a/developpment/drivers/ads1015/ads1050.h b/developpment/drivers/ads1015/ads1050.h new file mode 100644 index 0000000..5a21702 --- /dev/null +++ b/developpment/drivers/ads1015/ads1050.h @@ -0,0 +1,58 @@ +/* + * + * https://www.ti.com/lit/ds/symlink/ads1015.pdf?ts=1616137488325&ref_url=https%253A%252F%252Fwww.google.com%252F + * + * + * + * + * + */ + +#ifndef _ADS1015_H_ +#define _ADS1015_H_ + + +#define ADS115_MUX_AIN0P_AIN1N 0 // AINP=AIN0 and AINN=AIN1 +#define ADS115_MUX_AIN0P_AIN3N 1 // AINP=AIN0 and AINN=AIN3 +#define ADS115_MUX_AIN1P_AIN3N 2 // AINP=AIN1 and AINN=AIN3 +#define ADS115_MUX_AIN2P_AIN3N 3 // AINP=AIN2 and AINN=AIN3 +#define ADS115_MUX_AIN0_GND 4 // AIN0 and AINN=GND +#define ADS115_MUX_AIN0_GND 5 // AIN1 and AINN=GND +#define ADS115_MUX_AIN0_GND 6 // AIN2 and AINN=GND +#define ADS115_MUX_AIN0_GND 7 // AIN3 and AINN=GND + +//do not applymorethan VDD+0.3 V to the analog inputs of the device +#define ADS115_GAIN_6144 0 // ±6.144V +#define ADS115_GAIN_4096 1 // ±6.144V +#define ADS115_GAIN_2048 2 // ±6.144V +#define ADS115_GAIN_1024 3 // ±6.144V +#define ADS115_GAIN_512 4 // ±6.144V +#define ADS115_GAIN_256 5 // ±6.144V + +#define ADS115_MODE_CONTINIOUS 0 +#define ADS115_MODE_SINGLE 1 + + +#include +#include +#include +#include +#include "../../periferals/i2c/i2c_ch1_pImpL.hpp" +#include "../../management/errorHandling.h" + +class Ads1015 +{ + public: + Ads1015(i2c_ch1_pImpL* i2c,ErrorHandler* err); + setMultiplexer(uint8_t mode) + private: + ErrorHandler* errorHandling; + i2c_ch1_pImpL* i2c_ads1015; + +}; + + + + + +#endif //_ADS1015_H_ diff --git a/developpment/drivers/bh1750/bh1750.o b/developpment/drivers/bh1750/bh1750.o deleted file mode 100644 index 93f71e7..0000000 Binary files a/developpment/drivers/bh1750/bh1750.o and /dev/null differ diff --git a/developpment/drivers/pca9685/pca9685.cpp b/developpment/drivers/pca9685/pca9685.cpp index d5c740f..1570d9c 100644 --- a/developpment/drivers/pca9685/pca9685.cpp +++ b/developpment/drivers/pca9685/pca9685.cpp @@ -1,3 +1,13 @@ +/* + * TODO : output mde selection + * TODO : Implement chainning function to use it with more than one module + * + * + * + * + * + */ + #include "pca9685.h" @@ -7,7 +17,7 @@ Pca9685::Pca9685(i2c_ch1_pImpL* i2c, ErrorHandler* err) errorHandling = err; m_isExternalClock = 0; m_oscillatorFreq = PCA9685_FREQUENCY_OSCILLATOR; - setPwmFreq(1526); + setPwmFreq(1000); m_currentLED = PCA9685_LED_PWM_REG_START; errorHandling->addNewError(-1,__FILE__,"Selected duty cycle is too big",KILL); @@ -19,7 +29,9 @@ Pca9685::Pca9685(i2c_ch1_pImpL* i2c, ErrorHandler* err) errorHandling->addNewError(-7,__FILE__,"On Duty Cyle if greater than alowed maximum of 4095",SPARE); errorHandling->addNewError(-8,__FILE__,"Off Duty Cyle if greater than alowed maximum of 4095",SPARE); errorHandling->addNewError(-9,__FILE__,"Cumulation of the On & Off Duty Cyle if greater than alowed maximum of 4095",SPARE); - errorHandling->addNewError(-10,__FILE__,"On & Off Duty Cyle can't be equal to each other",SPARE); + errorHandling->addNewError(-10,__FILE__,"On & Off count cylces can't be equal to each other",SPARE); + errorHandling->addNewError(-11,__FILE__,"Duty cycle can't be greater than 100 percent",SPARE); + errorHandling->addNewError(-12,__FILE__,"This port number doesn't exist",KILL); } /*Refere to datasheet page 25 @@ -32,7 +44,7 @@ Pca9685::Pca9685(i2c_ch1_pImpL* i2c, ErrorHandler* err) */ void Pca9685::setPwmFreq(float frequency) -{ +{ if(frequency > 1526) { frequency = 1526; @@ -49,67 +61,231 @@ void Pca9685::setPwmFreq(float frequency) errorHandling->handleError(-4,__FILE__); } - m_currentPrescale = round((m_oscillatorFreq / ( 4096 * frequency)) - 1); - std::cout << unsigned(m_currentPrescale) << std::endl; + m_currentPrescale = round(((m_oscillatorFreq / ( 4096 * frequency))) - 1); + + + setPwmRaw(m_currentPrescale); +} + + + +//The impresition leves of thise device is out from this world this is a crude way from me trying to mitigate de awfullness. +//Tested with other module all to react the same +//maybe an external Clock could help with that but MCU level precision will never be reached !! Too sad +uint8_t Pca9685::compensatePrescale(uint8_t preScale) +{ + uint8_t compensation = 0; + + if(preScale > 236) + { + compensation = 12; + } + else if(preScale > 216 ) + { + compensation = 11; + } + else if(preScale > 200) + { + compensation = 10; + } + else if(preScale > 178) + { + compensation = 9; + } + else if(preScale > 157) + { + compensation = 8; + } + else if(preScale > 134) + { + compensation = 7; + } + else if(preScale > 114) + { + compensation = 6; + } + else if(preScale > 93) + { + compensation = 5; + } + else if(preScale > 71) + { + compensation = 4; + } + else if(preScale > 52) + { + compensation = 3; + } + else if(preScale > 32) + { + compensation = 2; + } + else if(preScale > 9) + { + compensation = 1; + } + return preScale - compensation; +} + + +// direct register acess and raw value to set PWM +// Datashhet page 25 +// FEh | PRE_SCALE7:0 | PRE_SCALE[7:0] | R/W | 0001 1110 | prescaler to program the PWM output frequency (default is 200 Hz) +void Pca9685::setPwmRaw(uint8_t preScale) +{ + m_currentPrescale = compensatePrescale(preScale); + if(m_currentPrescale < 3 ) + { + m_currentPrescale = 3; + errorHandling->handleError(-3,__FILE__); + } + else if(m_currentPrescale > 255) + { + m_currentPrescale = 255; + errorHandling->handleError(-4,__FILE__); + } + //std::cout << unsigned(m_currentPrescale) << " " << std::endl; sleep(); i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_PRESCALE, m_currentPrescale); wakeup(); } + +/*Refere to datasheet page 25 + * + * + * osc_clock + * Freq = _______________________ + * 4096 * (prescaler -1) + * + */ float Pca9685::getPwmFreq() { - m_currentPrescale = i2c_pca9685->readByte(PCA9685_I2C_ADDRESS,PCA9685_REG_PRESCALE); + m_currentPrescale = compensatePrescale(i2c_pca9685->readByte(PCA9685_I2C_ADDRESS,PCA9685_REG_PRESCALE)); m_currentPwmFreq = (m_oscillatorFreq / (4096 * ((float)m_currentPrescale + 1))); - std::cout << m_currentPwmFreq << std::endl; +// std::cout << m_currentPwmFreq << std::endl; return m_currentPwmFreq; } -void Pca9685::setDutyPercent(uint8_t ledNo, uint8_t on, uint8_t off) -{ - -} +/* + *The duty cylce is set in a special fation, rather than being relation between on and off time it is the timing definition of their ocurances. + * ON Meas after how many cycle counts from the PWM start will the risign edge occur + * OFF Means after heo many cycle counts from the PWM start will the falling edge will occur + * Than means : ON can't be equal to OFF anf OFF cna't be smaller than off + * 4096 as value is not a typo error it is used to turn one led fully on or off. Refere to datasheet page 21 + */ void Pca9685::setDutyRaw(uint8_t ledNo, uint16_t on, uint16_t off) { - m_currentLED = PCA9685_LED_PWM_REG_START + (ledNo * PCA9685_LED_NEXT_OFFSET); - + if(ledNo > 15) + { + errorHandling->handleError(-12,__FILE__); + } + if(on > 4095) { - on = 4095; + on = 4096; off = 0; errorHandling->handleError(-7,__FILE__); } if(off > 4095) { - off = 4095; + off = 4096; on = 0; errorHandling->handleError(-8,__FILE__); } if(on + off > 4095) { - off = 4095; + off = 4096; on = 0; errorHandling->handleError(-9,__FILE__); } if(on == off) { - off = 4095; + off = 4096; on = 0; errorHandling->handleError(-10,__FILE__); } + if(off == 0)// if there is no falling edge that measn that the signal is allways off + { + off = 4096; // set to fully off + on = 0; + } + + m_currentLED = PCA9685_LED_PWM_REG_START + (ledNo * PCA9685_LED_NEXT_OFFSET); i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED, on & 0xFF); i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED + PCA9685_PWM_ON_H_OFFSET, on >> 8); i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED + PCA9685_PWM_OFF_L_OFFSET, off & 0xFF); i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED + PCA9685_PWM_OFF_H_OFFSET, off >> 8); } -void Pca9685::setOnOff(uint8_t ledNo, bool onOff, bool invert) + +void Pca9685::setOnDutyPercent(uint8_t ledNo, uint8_t percent) { + uint16_t onLength = 0; + if(ledNo > 15) + { + errorHandling->handleError(-12,__FILE__); + } + + if(percent <= 100) + { + if(percent == 0) + { + setOnOff(ledNo, 0); + } + else if(percent == 100) + { + setOnOff(ledNo, 1); + } + else + { + onLength = (4095 * percent) / 100; + setDutyRaw(ledNo,0,onLength); + } + } + else + { + errorHandling->handleError(-11,__FILE__); + } +} + +//turns the given Port fully on or foo using the special value of 4096 +void Pca9685::setOnOff(uint8_t ledNo, bool onOff) +{ + uint16_t on, off = 0; + + if(ledNo > 15) + { + errorHandling->handleError(-12,__FILE__); + } + + if(onOff) + { + off = 0; + on = 4096; + } + else + { + off = 4096; + on = 0; + } + m_currentLED = PCA9685_LED_PWM_REG_START + (ledNo * PCA9685_LED_NEXT_OFFSET); + i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED, on & 0xFF); + i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED + PCA9685_PWM_ON_H_OFFSET, on >> 8); + i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED + PCA9685_PWM_OFF_L_OFFSET, off & 0xFF); + i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, m_currentLED + PCA9685_PWM_OFF_H_OFFSET, off >> 8); } + + +//Sets if internal or External clok would be used. +//if external clok will be used user must define it's frequency "uint32_t freq" in Hz +//The maximum supported external clok frequency if 50 Mhz +//Defaul intern Clok is 25 Mhz void Pca9685::confClk(bool internExtern, uint32_t freq) { if(internExtern) @@ -137,7 +313,7 @@ void Pca9685::confClk(bool internExtern, uint32_t freq) } } } - +//TODO void Pca9685::setOutputMode(bool mode) { @@ -147,6 +323,7 @@ void Pca9685::reset() { i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_MODE1, PCA9685_MODE1_RESTART); } + void Pca9685::sleep() { m_curMode = i2c_pca9685->readByte(PCA9685_I2C_ADDRESS,PCA9685_REG_MODE1); diff --git a/developpment/drivers/pca9685/pca9685.h b/developpment/drivers/pca9685/pca9685.h index 94daa20..06bd92e 100644 --- a/developpment/drivers/pca9685/pca9685.h +++ b/developpment/drivers/pca9685/pca9685.h @@ -1,3 +1,6 @@ +#ifndef _PCA9685_H_ +#define _PCA9685_H_ + #include #include #include @@ -5,6 +8,8 @@ #include "../../periferals/i2c/i2c_ch1_pImpL.hpp" #include "../../management/errorHandling.h" +// https://www.nxp.com/docs/en/data-sheet/PCA9685.pdf + // REGISTER ADDRESSES #define PCA9685_REG_MODE1 0x00 /**< Mode Register 1 */ #define PCA9685_REG_MODE2 0x01 /**< Mode Register 2 */ @@ -58,11 +63,12 @@ class Pca9685 public: Pca9685(i2c_ch1_pImpL* i2c,ErrorHandler* err); void setPwmFreq(float frequency); + void setPwmRaw(uint8_t preScale); + uint8_t compensatePrescale(uint8_t preScale); float getPwmFreq(); - void setDutyPercent(uint8_t ledNo, uint8_t on, uint8_t off); + void setOnDutyPercent(uint8_t ledNo, uint8_t percent); void setDutyRaw(uint8_t ledNo, uint16_t on, uint16_t off); - void setDutyMicroSecond(uint8_t ledNo, uint16_t on, uint16_t off); - void setOnOff(uint8_t ledNo, bool onOff, bool invert); + void setOnOff(uint8_t ledNo, bool onOff); void confClk(bool internExtern, uint32_t freq); void setOutputMode(bool mode); void reset(); @@ -78,3 +84,7 @@ class Pca9685 ErrorHandler* errorHandling; i2c_ch1_pImpL* i2c_pca9685; }; + + +#endif// _PCA9685_H_ + diff --git a/developpment/drivers/pca9685/pca9685.o b/developpment/drivers/pca9685/pca9685.o deleted file mode 100644 index 84bf647..0000000 Binary files a/developpment/drivers/pca9685/pca9685.o and /dev/null differ diff --git a/developpment/drivers/pf8574/pf8574lcd.c b/developpment/drivers/pf8574/pf8574lcd.c index 7dddde3..105af1a 100755 --- a/developpment/drivers/pf8574/pf8574lcd.c +++ b/developpment/drivers/pf8574/pf8574lcd.c @@ -40,14 +40,20 @@ int lcd_init(i2c_ch1_pImpL* i2c) // ||# # # # # # # # # # # # # # # # # # # #|| // ||# # # # # # # # # # # # # # # # # # # #|| // ------------------------------------------- -void lcd_display_string(char line, char pos, char* charvalue) +void lcd_display_string(unsigned char line, unsigned char pos, char* charvalue, unsigned char lenght) { - char setPosition = 0; - int i, S_length = 0; - //char buf[TOTAL_CHAR_CAP]; // buffer contenant la quantité de char dissponible sur une ligne + unsigned char setPosition = 0; + unsigned char i, S_length = 0; + S_length = strlen(charvalue); + if (lenght < S_length) + { + if (lenght > 0) + { + S_length = lenght; + } + } - S_length = strlen(charvalue); if (S_length > TOTAL_CHAR_CAP) { printf("LCD.C :\t La phrase est trop longue => %d MAX: %d \n", S_length, TOTAL_CHAR_CAP); @@ -96,7 +102,7 @@ void lcd_display_string(char line, char pos, char* charvalue) // Cette focntion nous pernet de faire pulser la ppin EN du lcd afin qu'il puisse // enregistrer les donées qui lui sont envoyées -void ldc_pulse_En(char data) +void ldc_pulse_En(unsigned char data) { i2c_pf8574->writeByte(LCD_ADDRS,data | EN | LCD_BACKLIGHT); usleep(100); @@ -107,7 +113,7 @@ void ldc_pulse_En(char data) // Cette fonction nous permet d'envoyer un information de 8 bits sous format // de 2x4 bites. Celà est necessaire du au fonctionnement de l'expendeur de port PCF8574 // qui est branché sur l'écran de facon a ce qu'il communiquer en 4 bits. -void lcd_write(char cmd, char mode) +void lcd_write(unsigned char cmd, unsigned char mode) { lcd_write_4bits(mode | (cmd & 0xF0)); lcd_write_4bits(mode | ((cmd << 4) & 0xF0)); @@ -115,7 +121,7 @@ void lcd_write(char cmd, char mode) // Fonction nous permettant d'nevoyer 4 bits dinformation sur le PC8574 ainsi que // le rétroéclairage. -void lcd_write_4bits(char data) +void lcd_write_4bits(unsigned char data) { i2c_pf8574->writeByte(LCD_ADDRS,data | LCD_BACKLIGHT); ldc_pulse_En(data); diff --git a/developpment/drivers/pf8574/pf8574lcd.h b/developpment/drivers/pf8574/pf8574lcd.h index 974b7cf..ae5e0e8 100755 --- a/developpment/drivers/pf8574/pf8574lcd.h +++ b/developpment/drivers/pf8574/pf8574lcd.h @@ -66,15 +66,15 @@ //adresse I2C du controlleur pour LCD #define LCD_ADDRS 0x27 -//Nombre max de char sur une ligne +//Nombre max de unsigned char sur une ligne #define TOTAL_CHAR_CAP 20 int lcd_init(i2c_ch1_pImpL* i2c); -void lcd_write_char( char charvalue); -void lcd_display_string(char line, char pos, char* charvalue); -void ldc_pulse_En(char data); -void lcd_write(char cmd, char mode); -void lcd_write_4bits(char data); +void lcd_write_char( unsigned char charvalue); +void lcd_display_string(unsigned char line, unsigned char pos, char* charvalue, unsigned char lenght); +void ldc_pulse_En(unsigned char data); +void lcd_write(unsigned char cmd, unsigned char mode); +void lcd_write_4bits(unsigned char data); diff --git a/developpment/drivers/pf8574/pf8574lcd.o b/developpment/drivers/pf8574/pf8574lcd.o deleted file mode 100644 index ff77426..0000000 Binary files a/developpment/drivers/pf8574/pf8574lcd.o and /dev/null differ diff --git a/developpment/interfacer.cpp b/developpment/interfacer.cpp index 30a6bd0..7f64555 100644 --- a/developpment/interfacer.cpp +++ b/developpment/interfacer.cpp @@ -19,50 +19,70 @@ ErrorHandler errorHandle; CommandManager commander; i2c_ch1_pImpL i2c(1, &errorHandle); -Bh1750 lightSens(&i2c); -Pca9685 pwmGenarator(&i2c, &errorHandle); +char char_array[TOTAL_CHAR_CAP]; +int freq = 0; int initPlatform() { - char char_array[TOTAL_CHAR_CAP]; - uint8_t pos = 0; lcd_init(&i2c); - strcpy(char_array, "Pwm Freq: "); - 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; } -void dummy() + +void pca9685_test() { - /* + Pca9685 pwmGenarator(&i2c, &errorHandle); + pwmGenarator.setOnDutyPercent(0,50); + for(int i = 3 ; i <= 255; i++) + { + pwmGenarator.setPwmRaw(i); + strcpy(char_array, "Pwm Freq: "); + lcd_display_string(1,0,char_array,0); + std::string Msg = std::to_string(pwmGenarator.getPwmFreq()); + strcpy(char_array, Msg.c_str()); + lcd_display_string(1,10, char_array, 7); + strcpy(char_array, "Hz"); + lcd_display_string(1,18, char_array, 7); + usleep(200000); + freq = getchar(); + } +} + +void bh1750_test() +{ + Bh1750 lightSens(&i2c); while(1) { // std::cout << "value "<< lightSens.continious(BH1750_CONTINUOUS_HIGH_RES_MODE_1,1) << " Lux" <