diff --git a/FC_InferfaceBoard/DFRobot_GP8403.h b/FC_InferfaceBoard/DFRobot_GP8403.h new file mode 100644 index 0000000..2fedc87 --- /dev/null +++ b/FC_InferfaceBoard/DFRobot_GP8403.h @@ -0,0 +1,104 @@ +/*! + ** Modified by Scitech Korea Inc., Changwoo Park + * @file DFRobot_GP8403.h + * @brief This is a method description file for the DAC module + * @copyright Copyright (c) 2021 DFRobot Co.Ltd (http://www.dfrobot.com) + * @license The MIT License (MIT) + * @author [TangJie](jie.tang@dfrobot.com) + * @version V1.0 + * @date 2022-03-07 + * @url https://github.com/DFRobot/DFRobot_Microphone + */ +#ifndef _DFROBOT_GP8403_H_ +#define _DFROBOT_GP8403_H + + +#define GP8302_STORE_TIMING_HEAD 0x02 ///< Store function timing start head +#define GP8302_STORE_TIMING_ADDR 0x10 ///< The first address for entering store timing +#define GP8302_STORE_TIMING_CMD1 0x03 ///< The command 1 to enter store timing +#define GP8302_STORE_TIMING_CMD2 0x00 ///< The command 2 to enter store timing +#define GP8302_STORE_TIMING_DELAY 10 ///< Store procedure interval delay time: 10ms, more than 7ms +#define GP8302_STORE_TIMING_DELAY 10 ///< Store procedure interval delay time: 10ms, more than 7ms +#define I2C_CYCLE_TOTAL 5 ///< Total I2C communication cycle +#define I2C_CYCLE_BEFORE 1 ///< The first half cycle 2 of the total I2C communication cycle +#define I2C_CYCLE_AFTER 2 ///< The second half cycle 3 of the total I2C communication cycle + + +//#define ENABLE_DBG //!< Open the macro and you can see the detailed procedure of the program +#ifdef ENABLE_DBG +#define DBG(...) {Serial.print("[");Serial.print(__FUNCTION__); Serial.print("(): "); Serial.print(__LINE__); Serial.print(" ] "); Serial.println(__VA_ARGS__);} +#else +#define DBG(...) +#endif +#define GP8302_CONFIG_CURRENT_REG 0x02 +#define OUTPUT_RANGE 0X00 +class DFRobot_GP8403 +{ +public: + /** + * @enum eOutPutRange_t + * @brief Analog voltage output range select + */ + typedef enum{ + eOutputRange5V = 0X00, + eOutputRange10V = 0X11, + }eOutPutRange_t; + /** + * @brief DFRobot_GP8403 constructor + * @param pWire I2C object + * @param addr I2C address + */ + DFRobot_GP8403(TwoWire *pWire = &Wire,uint8_t addr = 0x58); + /** + * @fn begin + * @brief Initialize the module + */ + uint8_t begin(void); + + /** + * @fn setDACOutRange + * @brief Set DAC output range + * @param range DAC output range + * @return NONE + */ + void setDACOutRange(eOutPutRange_t range); + + /** + * @fn setDACOutVoltage + * @brief Set output DAC voltage of different channels + * @param data The voltage value to be output + * @param channel Output channel. 0: channel 0; 1: channel 1; 2: all the channels + * @return NONE + */ + void setDACOutVoltage(uint16_t data,uint8_t channel); + /** + * @brief Save the set voltage in the chip + */ + void store(void); + +protected: + void startSignal(void); + void stopSignal(void); + uint8_t recvAck(uint8_t ack); + uint8_t sendByte(uint8_t data, uint8_t ack = 0, uint8_t bits = 8, bool flag = true); + +private: +/** + * @fn writeReg + * @brief Write register value through IIC bus + * @param reg Register address 8bits + * @param pBuf Storage cache to write data in + * @param size The length of data to be written + */ + void writeReg(uint8_t reg, void *pBuf, size_t size); + TwoWire *_pWire; + uint8_t _addr; + uint16_t voltage = 0; + int _scl= SCL; + int _sda = SDA; + void sendData(uint16_t data, uint8_t channel); +}; + + + +#endif diff --git a/FC_InferfaceBoard/FC_InferfaceBoard.ino b/FC_InferfaceBoard/FC_InferfaceBoard.ino index be95fc5..8fe4c2b 100644 --- a/FC_InferfaceBoard/FC_InferfaceBoard.ino +++ b/FC_InferfaceBoard/FC_InferfaceBoard.ino @@ -54,6 +54,14 @@ int Wait_485_cnt; // ---------- I2C (Analog Output, DAC) DFRobot_GP8403 AO_0(&Wire,0x58); +DFRobot_GP8403 AO_1(&Wire,0x59); +DFRobot_GP8403 AO_2(&Wire,0x5A); +DFRobot_GP8403 AO_3(&Wire,0x5B); +DFRobot_GP8403 AO_4(&Wire,0x5C); +DFRobot_GP8403 AO_5(&Wire,0x5D); +DFRobot_GP8403 AO_6(&Wire,0x5E); +DFRobot_GP8403 AO_7(&Wire,0x5F); + int voltOffset = 185; // ========== ========== Processing @@ -161,7 +169,7 @@ void loop() { }else if(cmd=="AO!"){ dataSize = demuxNum(cmdData, data); - client.print(Prcss_AO(data, dataSize)); + client.print(Prcss_AO_Write(data, dataSize)); }else if(cmd=="PV?"){ client.print(Prcss_PV_Read()); diff --git a/FC_InferfaceBoard/GP8403.ino b/FC_InferfaceBoard/GP8403.ino new file mode 100644 index 0000000..af8a210 --- /dev/null +++ b/FC_InferfaceBoard/GP8403.ino @@ -0,0 +1,217 @@ + +void GP8403_setup() { + + while(AO_0.begin()!=0){ + Serial.println("AO_0 init error"); + delay(1000); + } + Serial.println("AO_0 init succeed"); + //Set DAC output range + AO_0.setDACOutRange(AO_0.eOutputRange5V); + //Set the output value for DAC channel 0, range 0-5000 + AO_0.setDACOutVoltage(0, 0); + delay(100); + //Store data in the chip + AO_0.store(); + + + while(AO_1.begin()!=0){ + Serial.println("AO_1 init error"); + delay(1000); + } + Serial.println("AO_1 init succeed"); + //Set DAC output range + AO_1.setDACOutRange(AO_0.eOutputRange10V); + //Set the output value for DAC channel 0, range 0-5000 + AO_1.setDACOutVoltage(0, 0); + delay(100); + //Store data in the chip + AO_1.store(); +} + +DFRobot_GP8403::DFRobot_GP8403(TwoWire *pWire,uint8_t addr) +{ + _pWire = pWire; + _addr = addr; +} + +uint8_t DFRobot_GP8403::begin(void) +{ + _pWire->begin(); + _pWire->setClock(400000); + _pWire->beginTransmission(_addr); + _pWire->write(OUTPUT_RANGE); + if(_pWire->endTransmission() != 0){ + Serial.println(_pWire->endTransmission()); + return 1; + } + return 0; +} + +void DFRobot_GP8403::setDACOutRange(eOutPutRange_t range) +{ + if(range == eOutPutRange_t::eOutputRange5V) + { + voltage = 5000; + }else{ + voltage = 10000; + } + writeReg(OUTPUT_RANGE,&range,1); +} +void DFRobot_GP8403::setDACOutVoltage(uint16_t data, uint8_t channel) +{ + uint16_t dataTransmission = (uint16_t)(((float)data / (voltage + voltOffset)) * 4095); + DBG(dataTransmission); + dataTransmission = dataTransmission << 4; + sendData(dataTransmission,channel); +} + + +void DFRobot_GP8403::sendData(uint16_t data, uint8_t channel) +{ + if(channel == 0){ + _pWire->beginTransmission(_addr); + _pWire->write(GP8302_CONFIG_CURRENT_REG); + _pWire->write(data & 0xff); + _pWire->write((data >>8) & 0xff); + _pWire->endTransmission(); + DBG(channel); + }else if(channel == 1){ + _pWire->beginTransmission(_addr); + _pWire->write(GP8302_CONFIG_CURRENT_REG<<1); + _pWire->write(data & 0xff); + _pWire->write((data >>8) & 0xff); + _pWire->endTransmission(); + DBG(channel); + }else{ + _pWire->beginTransmission(_addr); + _pWire->write(GP8302_CONFIG_CURRENT_REG); + _pWire->write(data & 0xff); + _pWire->write((data >>8) & 0xff); + _pWire->write(data & 0xff); + _pWire->write((data >>8) & 0xff); + _pWire->endTransmission(); + DBG(channel); + } +} + + +void DFRobot_GP8403::store(){ + #if defined(ESP32) + _pWire->~TwoWire(); + #elif !defined(ESP8266) + _pWire->end(); + #endif + pinMode(_scl, OUTPUT); + pinMode(_sda, OUTPUT); + digitalWrite(_scl, HIGH); + digitalWrite(_sda, HIGH); + startSignal(); + sendByte(GP8302_STORE_TIMING_HEAD, 0, 3, false); + stopSignal(); + startSignal(); + sendByte(GP8302_STORE_TIMING_ADDR); + sendByte(GP8302_STORE_TIMING_CMD1); + stopSignal(); + + startSignal(); + sendByte(_addr<<1, 1); + sendByte(GP8302_STORE_TIMING_CMD2, 1); + sendByte(GP8302_STORE_TIMING_CMD2, 1); + sendByte(GP8302_STORE_TIMING_CMD2, 1); + sendByte(GP8302_STORE_TIMING_CMD2, 1); + sendByte(GP8302_STORE_TIMING_CMD2, 1); + sendByte(GP8302_STORE_TIMING_CMD2, 1); + sendByte(GP8302_STORE_TIMING_CMD2, 1); + sendByte(GP8302_STORE_TIMING_CMD2, 1); + stopSignal(); + + delay(GP8302_STORE_TIMING_DELAY); + + startSignal(); + sendByte(GP8302_STORE_TIMING_HEAD, 0, 3, false); + stopSignal(); + startSignal(); + sendByte(GP8302_STORE_TIMING_ADDR); + sendByte(GP8302_STORE_TIMING_CMD2); + stopSignal(); + _pWire->begin(); +} + +void DFRobot_GP8403::startSignal(void){ + digitalWrite(_scl,HIGH); + digitalWrite(_sda,HIGH); + delayMicroseconds(I2C_CYCLE_BEFORE); + digitalWrite(_sda,LOW); + delayMicroseconds(I2C_CYCLE_AFTER); + digitalWrite(_scl,LOW); + delayMicroseconds(I2C_CYCLE_TOTAL); +} + +void DFRobot_GP8403::stopSignal(void){ + digitalWrite(_sda,LOW); + delayMicroseconds(I2C_CYCLE_BEFORE); + digitalWrite(_scl,HIGH); + delayMicroseconds(I2C_CYCLE_TOTAL); + digitalWrite(_sda,HIGH); + delayMicroseconds(I2C_CYCLE_TOTAL); +} + + +uint8_t DFRobot_GP8403::sendByte(uint8_t data, uint8_t ack, uint8_t bits, bool flag){ + for(int i=bits-1; i>=0;i--){ + if(data & (1< 250) break; + } + ack_=digitalRead(_sda); + delayMicroseconds(I2C_CYCLE_BEFORE); + digitalWrite(_scl,LOW); + delayMicroseconds(I2C_CYCLE_AFTER); + pinMode(_sda,OUTPUT); + return ack_; +} +void DFRobot_GP8403::writeReg(uint8_t reg, void *pBuf, size_t size) +{ + uint8_t *_pBuf = (uint8_t*)pBuf; + _pWire->beginTransmission(_addr); + _pWire->write(reg); + + for(size_t i = 0; i < size; i++){ + _pWire->write(_pBuf[i]); + } + _pWire->endTransmission(); +} + diff --git a/FC_InferfaceBoard/Processes.ino b/FC_InferfaceBoard/Processes.ino index ec23fd0..5f33a91 100644 --- a/FC_InferfaceBoard/Processes.ino +++ b/FC_InferfaceBoard/Processes.ino @@ -90,7 +90,7 @@ String Prcss_AI_Read(){ return str + FIN; } -String Prcss_AO(unsigned int data[], int dataSize){ +String Prcss_AO_Write(unsigned int data[], int dataSize){ String str = "AO!:"; int t = millis(); for(int i=0 ; i