DACs and bridge App

This commit is contained in:
Kevin Santo Cappuccio 2023-07-02 13:54:14 -07:00
parent ec010a16f6
commit 4f4d285e37
10 changed files with 665 additions and 83 deletions

View File

@ -1,10 +0,0 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@ -0,0 +1,455 @@
/*!
@file mcp4725.cpp
@author Gavin Lyons
@brief MCP4725 DAC library cpp file.
*/
#include "mcp4725.hpp"
/*!
@brief Constructor for class MCP4725_PIC0
@param refV The the reference voltage to be set in Volts.
*/
MCP4725_PICO::MCP4725_PICO(float refV)
{
setReferenceVoltage(refV);
}
/*!
@brief Init & config i2c
@param addr I2C address 8 bit address 0x6?.
@param i2c_type I2C instance of port, IC20 or I2C1.
@param CLKspeed I2C Bus Clock speed in Kbit/s. see 7.1 datasheet
@param SDApin I2C Data GPIO
@param SCLKpin I2C Clock GPIO
@return true if success , false for failure
*/
bool MCP4725_PICO::begin(MCP4725_I2C_Addr_e addr, i2c_inst_t* i2c_type, uint16_t CLKspeed, uint8_t SDApin, uint8_t SCLKpin)
{
uint8_t rxData = 0;
// init I2c pins and interface
_i2cAddress = addr;
_i2c = i2c_type;
_SClkPin = SCLKpin;
_SDataPin = SDApin;
_CLKSpeed = CLKspeed;
gpio_set_function(_SDataPin, GPIO_FUNC_I2C);
gpio_set_function(_SClkPin, GPIO_FUNC_I2C);
gpio_pull_up(_SDataPin);
gpio_pull_up(_SClkPin);
i2c_init(_i2c, _CLKSpeed * 1000);
busy_wait_ms(50);
// check connection?
return isConnected();
}
/*!
@brief Switch off the I2C interface and return I2C GPIO to default state
*/
void MCP4725_PICO::deinitI2C()
{
gpio_set_function(_SDataPin, GPIO_FUNC_NULL);
gpio_set_function(_SClkPin, GPIO_FUNC_NULL);
i2c_deinit(_i2c);
}
/*!
@brief Checks if DAC is connected.
@return true if DAC is connected , false if not
*/
bool MCP4725_PICO::isConnected()
{
int ReturnCode = 0;
uint8_t rxData = 0;
// check connection?
ReturnCode = i2c_read_timeout_us(_i2c, _i2cAddress , &rxData, 1, false, MCP4725_I2C_DELAY);
if (ReturnCode < 1){ // no bytes read back from device or error issued
if (_serialDebug == true)
{
printf("1202 PICO_MCP4725::is connected: \r\n");
printf("Check Connection, Return code :: %d ,RX data :: %u \r\n", ReturnCode , rxData);
}
return false;
}
return true;
}
/*!
@brief Sets the reference voltage.
@param voltage the reference voltage to be set, called from constructor.
*/
void MCP4725_PICO::setReferenceVoltage(float voltage)
{
if (voltage == 0)
_refVoltage = MCP4725_REFERENCE_VOLTAGE;
else
_refVoltage = voltage;
_bitsPerVolt = (float)MCP4725_STEPS / _refVoltage;
}
/*!
@brief Gets the reference voltage.
@return The reference voltage in volts.
*/
float MCP4725_PICO::getReferenceVoltage(){return _refVoltage;}
/*!
@brief Set voltage out based on DAC input code.
@param InputCode 0 to MCP4725_MAX_VALUE.
@param mode MCP4725DAC mode, see enum MCP4725_CmdType_e.
@param powerType MCP4725DAC power type, see enum MCP4725_PowerType_e
@return output of writeCommand method, true for success, false for failure.
*/
bool MCP4725_PICO::setInputCode(uint16_t InputCode, MCP4725_CmdType_e mode, MCP4725_PowerDownType_e powerType)
{
if (_safetyCheck == true)
{
if (InputCode > MCP4725_MAX_VALUE)
InputCode = MCP4725_MAX_VALUE;
}
return writeCommand(InputCode, mode, powerType);
}
/*!
@brief Set voltage out based on voltage input in volts.
@param voltage 0 to_MCP4725_REFERENCE_VOLTAGE, voltage out
@param mode MCP4725DAC mode, see enum MCP4725_CmdType_e.
@param powerType MCP4725DAC power type, see enum MCP4725_PowerType_e
@return output of writeCommand method, true for success, false for failure.
*/
bool MCP4725_PICO::setVoltage(float voltage, MCP4725_CmdType_e mode, MCP4725_PowerDownType_e powerType)
{
uint16_t voltageValue = 0;
// Convert voltage to DAC bits
//xx,xx,xx,xx,D11,D10,D9,D8 ,D7,D6,D4,D3,D2,D9,D1,D0
if (_safetyCheck == true)
{
if (voltage >= _refVoltage)
voltageValue = MCP4725_MAX_VALUE;
else if (voltage <= 0)
voltageValue = 0; //make sure value never below zero
else
voltageValue = voltage * _bitsPerVolt;
}
else if (_safetyCheck == false)
{
voltageValue = voltage * _bitsPerVolt;
}
return writeCommand(voltageValue, mode, powerType);
}
/*!
@brief get current DAC InputCode from DAC register
@return DAC InputCode :or 0xFFFF if I2C error
*/
uint16_t MCP4725_PICO::getInputCode()
{
uint16_t inputCode = readRegister(MCP4725_ReadDACReg);
// InputCode = D11,D10,D9,D8,D7,D6,D5,D4, D3,D2,D1,D0,x,x,x,x
if (inputCode != MCP4725_ERROR)
return inputCode >> 4; //0,0,0,0,D11,D10,D9,D8, D7,D6,D5,D4,D3,D2,D1,D0
else
return inputCode; // i2c Error return 0xFFFF
}
/*!
@brief get DAC inputCode from DAC register & convert to volts
@return DAC voltage or 0xFFFF if I2C error
*/
float MCP4725_PICO::getVoltage()
{
float InputCode = getInputCode();
if (InputCode != MCP4725_ERROR)
return InputCode / _bitsPerVolt;
else
return InputCode; // i2c Error return 0xFFFF
}
/*!
@brief Read DAC inputCode from EEPROM
@return stored EEPROM inputcode value or 0xFFFF if I2C error
*/
uint16_t MCP4725_PICO::getStoredInputCode()
{
uint16_t inputCode = readRegister(MCP4725_ReadEEPROM);
//InputCode = x,PD1,PD0,x,D11,D10,D9,D8, D7,D6,D5,D4,D3,D2,D1,D0
if (inputCode != MCP4725_ERROR)
return inputCode & 0x0FFF; //0,0,0,0,D11,D10,D9,D8, D7,D6,D5,D4,D3,D2,D1,D0
else
return inputCode; // i2c Error return 0xFFFF
}
/*!
@brief Read stored DAC InputCode from EEPROM & convert to voltage
@return stored EEPROM voltage or 0xFFFF if I2C error
*/
float MCP4725_PICO::getStoredVoltage()
{
float InputCode = getStoredInputCode();
if (InputCode != MCP4725_ERROR)
return InputCode / _bitsPerVolt;
else
return InputCode;
}
/*!
@brief Get current power type from DAC register
@return power type or 0xFFFF if I2C error
@note Power type corresponds to enum MCP4725_PowerDownType_e
*/
uint16_t MCP4725_PICO::getPowerType()
{
uint16_t powerTypeValue = readRegister(MCP4725_ReadSettings);
//powerTypeValue = BSY,POR,xx,xx,xx,PD1,PD0,xx
if (powerTypeValue != MCP4725_ERROR){
powerTypeValue &= 0x0006; //00,00,00,00,00,PD1,PD0,00
return powerTypeValue >> 1; //00,00,00,00,00,00,PD1,PD0
}else{
return powerTypeValue;
}
}
/*!
@brief Get stored power type from EEPROM
@return EEPROM power type or 0xFFFF if I2C error
@note Power type corresponds to enum MCP4725_PowerDownType_e
*/
uint16_t MCP4725_PICO::getStoredPowerType()
{
uint16_t powerTypeValue = readRegister(MCP4725_ReadEEPROM);
//powerTypeValue = x,PD1,PD0,xx,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0
if (powerTypeValue != MCP4725_ERROR)
{
powerTypeValue = powerTypeValue << 1; //PD1,PD0,xx,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0,00
return powerTypeValue >> 14; //00,00,00,00,00,00,00,00,00,00,00,00,00,00,PD1,PD0
}else
{
return powerTypeValue;
}
}
/*!
@brief get EEPROM writing status from DAC register
@return 1 for completed or 0( busy or I2C error)
@note The BSY bit is low (during the EEPROM writing)
*/
bool MCP4725_PICO::getEEPROMBusyFlag()
{
uint16_t registerValue = readRegister(MCP4725_ReadSettings);
//register value = BSY,POR,xx,xx,xx,PD1,PD0,xx
bool ReturnValue = false;
if (registerValue != MCP4725_ERROR)
{
ReturnValue = ((registerValue >> 7) & 0x01);
return ReturnValue; //1 - Not Busy, 0 - Busy
}else
{
return ReturnValue; // I2C error
}
}
/*!
@brief Writes data to DAC register or EEPROM
@param inputCode 0 to MCP4725_MAX_VALUE input code
@param mode MCP4725DAC mode, see enum MCP4725_CmdType_e.
@param PowerType MCP4725 power type, see enum MCP4725_PowerType_e
@return true for success, false for failure.
*/
bool MCP4725_PICO::writeCommand(uint16_t inputCode, MCP4725_CmdType_e mode, MCP4725_PowerDownType_e powerType)
{
uint8_t dataBuffer[3];
uint8_t lowByte = 0;
uint8_t highByte = 0;
int ReturnCode = 0;
switch (mode)
{
case MCP4725_FastMode:
//C2=0,C1=0,PD1,PD0,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0
lowByte = (uint8_t)(inputCode & 0x00FF);
highByte = (uint8_t)((inputCode >> 8) & 0x00FF);
dataBuffer[0] = mode | (powerType << 4) | highByte; //C2,C1,PD1,PD0,D11,D10,D9,D8
dataBuffer[1] = lowByte; //D7,D6,D5,D4,D3,D2,D1,D0
ReturnCode = i2c_write_timeout_us(_i2c, _i2cAddress, dataBuffer, 2 , false, MCP4725_I2C_DELAY);
if (ReturnCode < 1)
{
if (_serialDebug == true)
{
printf("1203 : I2C error :: WriteCommand 1 \r\n");
printf("Tranmission code : %d \r\n", ReturnCode );
busy_wait_ms(100);
}
return false;
}
break;
case MCP4725_RegisterMode:
//C2=0,C1=1,C0=0,x,x,PD1,PD0,x,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0,x,x,x,x
case MCP4725_EEPROM_Mode:
//C2=0,C1=1,C0=1,x,x,PD1,PD0,x,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0,x,x,x,x
inputCode = inputCode << 4; //D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0,x,x,x,x
lowByte = (uint8_t)(inputCode & 0x00FF);
highByte = (uint8_t)((inputCode >> 8) & 0x00FF);
dataBuffer[0] = mode | (powerType << 1); // C2,C1,C0,x,x,PD1,PD0,x
dataBuffer[1] = highByte; // D11,D10,D9,D8,D7,D6,D5,D4
dataBuffer[2] = lowByte; // D3,D2,D1,D0,x,x,x,x
ReturnCode = i2c_write_timeout_us(_i2c, _i2cAddress, dataBuffer, 3 , false, MCP4725_I2C_DELAY);
if (ReturnCode < 1)
{
if (_serialDebug == true)
{
printf("1204 : I2C error :: writeCommand 2 \r\n");
printf("Tranmission code : %d \r\n", ReturnCode );
busy_wait_ms(100);
}
return false;
}
break;
}
if (mode == MCP4725_EEPROM_Mode)
{
if (getEEPROMBusyFlag() == true)
return true;
busy_wait_ms(MCP4725_EEPROM_WRITE_TIME); //typical EEPROM write time 25 mSec
if (getEEPROMBusyFlag() == true)
return true;
busy_wait_ms(MCP4725_EEPROM_WRITE_TIME); //maximum EEPROM write time 25*2 mSec
}
return true;
}
/*!
@brief Read DAC register
@param mode MCP4725DAC datatype 1 3 or 5, see enum MCP4725_ReadType_e.
@return Requested value of read or type 0XFFFF if I2c error
*/
uint16_t MCP4725_PICO::readRegister(MCP4725_ReadType_e readType)
{
uint16_t dataWord = readType;
uint8_t dataBuffer[6];
int ReturnCode = 0;
/*Format of read data :
== Settings data one byte
BSY,POR,xx,xx,xx,PD1,PD0,xx,
== DAC register data 3 byte(1st 1 don't care)
D11,D10,D9,D8,D7,D6,D5,D4, D3,D2,D1,D0,xx,xx,xx,xx,
== EEPROM data 5 byte (1st 3 don't care)
xx,PD1,PD0,xx,D11,D10,D9,D8, D7,D6,D5,D4,D3,D2,D1,D0
*/
switch (readType)
{
case MCP4725_ReadSettings: // Read one byte settings
ReturnCode = i2c_read_timeout_us(_i2c, _i2cAddress, dataBuffer, 1, false, MCP4725_I2C_DELAY);
dataWord = dataBuffer[0];
break;
case MCP4725_ReadDACReg: // Read 3 bytes DAC register data, skip first 1 don't care
ReturnCode = i2c_read_timeout_us(_i2c, _i2cAddress, dataBuffer, 3, false, MCP4725_I2C_DELAY);
dataWord = dataBuffer[1];
dataWord = (dataWord << 8) | dataBuffer[2];
break;
case MCP4725_ReadEEPROM: // Read 5 bytes EEPROM data , first 3 don't care
ReturnCode = i2c_read_timeout_us(_i2c, _i2cAddress, dataBuffer, 5, false, MCP4725_I2C_DELAY);
dataWord = dataBuffer[3];
dataWord = (dataWord << 8) | dataBuffer[4];
break;
}
if (ReturnCode < 1)
{ // no bytes read back from device or error issued
if (_serialDebug == true)
{
printf("1205 I2C Error readRegister : \r\n");
printf("Tranmission Code :: %d\r\n", ReturnCode);
busy_wait_ms(100);
}
return MCP4725_ERROR;
}else{
return dataWord;
}
}
/*!
@brief Setter for serial debug flag
@param onOff Turns or or off the serial debug flag
*/
void MCP4725_PICO::setSerialDebugFlag(bool onOff){_serialDebug = onOff;}
/*!
@brief Gets the serial Debug flag value
@return The serial Debug flag value
*/
bool MCP4725_PICO::getSerialDebugFlag(void){return _serialDebug;}
/*!
@brief Setter for safety Check flag
@param onOff Turns or or off the safety check flag
*/
void MCP4725_PICO::setSafetyCheckFlag(bool onOff){_safetyCheck = onOff;}
/*!
@brief Gets the safety Check flag value
@return The safety Check flag value
*/
bool MCP4725_PICO::getSafetyCheckFlag(){return _safetyCheck;}
/*!
@brief General Call, name from datasheet section 7.3
@param typeCall Reset or wakeup see MCP4725_GeneralCallType_e.
@return True on success, false on I2c error OR wrong input(GeneralCallAddress)
@note
1. Reset MCP4725 & upload data from EEPROM to DAC register.
Immediately after reset event, uploads contents of EEPROM into the DAC reg.
2. Wake up & upload value from DAC register,
Current power-down bits are set to normal, EEPROM power-down bit are not affected
*/
bool MCP4725_PICO::GeneralCall(MCP4725_GeneralCallType_e typeCall){
if (typeCall == MCP4725_GeneralCallAddress) {return false;}
int ReturnCode = 0;
uint8_t dataBuffer[1];
dataBuffer[0] = (uint8_t)typeCall;
// Note I2c address is MCP4725_GENERAL_CALL_ADDRESS
ReturnCode = i2c_write_timeout_us(_i2c, (uint8_t)MCP4725_GeneralCallAddress, dataBuffer, 1 , false, MCP4725_I2C_DELAY);
if (ReturnCode < 1)
{ // no bytes read back from device or error issued
if (_serialDebug == true)
{
printf("1206 I2C Error General Call : \r\n");
printf("Tranmission Code :: %d\r\n", ReturnCode);
busy_wait_ms(100);
}
return false;
}else{
return true;
}
}
// ------------------ EOF ------------------------

View File

@ -0,0 +1,131 @@
/*!
@file mcp4725.hpp
@author Gavin Lyons
@brief Library header file for MCP4725 PICO DAC library.
@note See URL for full details. https://github.com/gavinlyonsrepo/MCP4725_PICO
*/
#ifndef __MCP4725_DAC_H
#define __MCP4725_DAC_H
// Libraries
#include <stdio.h> // optional for printf debug error messages
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include <cmath> // for pow() function
// Section Enums
/*! 8-bit i2c address. */
typedef enum : uint8_t
{
MCP4725A0_Addr_A00 = 0x60, /**< MCP4725A0 with A0 = GND */
MCP4725A0_Addr_A01 = 0x61, /**< MCP4725A0 with A0 = VCC */
MCP4725A1_Addr_A00 = 0x62, /**< MCP4725A1 with A0 = GND */
MCP4725A1_Addr_A01 = 0x63, /**< MCP4725A1 with A0 = VCC */
MCP4725A2_Addr_A00 = 0x64, /**< MCP4725A2 with A0 = GND */
MCP4725A2_Addr_A01 = 0x65 /**< MCP4725A2 with A0 = VCC */
}MCP4725_I2C_Addr_e; // 8-bit i2c address
/*! DAC register, command bits C2C1C0 */
typedef enum : uint8_t
{
MCP4725_FastMode = 0x00, /**< Writes data to DAC register */
MCP4725_RegisterMode = 0x40, /**< Writes data & config bits to DAC register */
MCP4725_EEPROM_Mode = 0x60 /**< Writes data & config bits to DAC register & EEPROM */
}MCP4725_CmdType_e; // DAC register, command bits C2C1C0 */
/*! DAC register, power down bits PD1 PD0 , BSY,POR,xx,xx,xx,PD1,PD0,xx */
typedef enum : uint8_t
{
MCP4725_PowerDown_Off = 0x00, /**< Power down off draws 0.40mA no load & 0.29mA max load */
MCP4725_PowerDown_1kOhm = 0x01, /**< Power down on, with 1.0 kOhm to GND, draws ~60nA */
MCP4725_PowerDown_100kOhm = 0x02, /**< Power down on, with 100 kOhm to GND */
MCP4725_PowerDown_500kOhm = 0x03 /**< Power down on, with 500 kOhm to GND */
}MCP4725_PowerDownType_e; // DAC register, power down bits PD1 PD0 , BSY,POR,xx,xx,xx,PD1,PD0,xx */
/*! DAC library read register type */
typedef enum : uint8_t
{
MCP4725_ReadSettings = 1, /**< Read 1 byte, Settings data */
MCP4725_ReadDACReg = 3, /**< Read 3 bytes, DAC register data */
MCP4725_ReadEEPROM = 5 /**< Read 5 bytes, EEPROM data */
}MCP4725_ReadType_e; // DAC library read register type
/*! DAC general call command datasheet 7.3 */
typedef enum : uint8_t
{
MCP4725_GeneralCallAddress = 0x00, /**< General call address */
MCP4725_GeneralCallReset = 0x06, /**< General call reset command */
MCP4725_GeneralCallWakeUp = 0x09 /**< General call wake-up command */
}MCP4725_GeneralCallType_e; // DAC general call command datasheet 7.3
// Section Definition's
// I2C interface Comms related
#define MCP4725_I2C_DELAY 50000 /**< uS delay , I2C timeout */
#define MCP4725_ERROR 0xFFFF /**< returns this value if I2C bus error from some methods */
#define MCP4725_EEPROM_WRITE_TIME 25 /**< mSec Memory write time, maximum 50 mSec */
// DAC voltage levels
#define MCP4725_REFERENCE_VOLTAGE 3.3 /**< supply-reference Voltage in volts */
#define MCP4725_RESOLUTION 12 /**< resolution in bits , 12-bit */
#define MCP4725_STEPS pow(2, (MCP4725_RESOLUTION)) /**< quantity of DAC steps 2^12-bits = 4096 */
#define MCP4725_MAX_VALUE ((MCP4725_STEPS) - 1) /**< Max value = 4096 -1 , 0 to 4095 */
/*!
@brief Class for MCP4725_PIC0 DAC
*/
class MCP4725_PICO
{
public:
MCP4725_PICO(float refV = MCP4725_REFERENCE_VOLTAGE);
bool begin(MCP4725_I2C_Addr_e addr, i2c_inst_t* type, uint16_t speed, uint8_t SDA, uint8_t SCLK);
bool isConnected();
bool GeneralCall(MCP4725_GeneralCallType_e);
void deinitI2C();
void setReferenceVoltage(float value);
float getReferenceVoltage(void);
bool setInputCode(uint16_t inputCode, MCP4725_CmdType_e = MCP4725_FastMode, MCP4725_PowerDownType_e = MCP4725_PowerDown_Off);
uint16_t getInputCode(void);
bool setVoltage(float voltage, MCP4725_CmdType_e = MCP4725_FastMode, MCP4725_PowerDownType_e = MCP4725_PowerDown_Off);
float getVoltage(void);
uint16_t getStoredInputCode(void);
float getStoredVoltage(void);
uint16_t getPowerType(void);
uint16_t getStoredPowerType(void);
void setSerialDebugFlag(bool onOff);
bool getSerialDebugFlag(void);
void setSafetyCheckFlag(bool onOff);
bool getSafetyCheckFlag(void);
private:
//I2c related
MCP4725_I2C_Addr_e _i2cAddress;
i2c_inst_t *_i2c; // i2C port number, i2c0 or i2c1
uint8_t _SDataPin;
uint8_t _SClkPin;
uint16_t _CLKSpeed = 100; // I2C bus speed in khz
bool _serialDebug = false; // Outputs Messages for debugging to serial port true = on
float _refVoltage;
uint16_t _bitsPerVolt;
bool _safetyCheck = true; // Safety check for voltage level's , true = on
bool getEEPROMBusyFlag(void);
bool writeCommand(uint16_t value, MCP4725_CmdType_e mode, MCP4725_PowerDownType_e powerType);
uint16_t readRegister(MCP4725_ReadType_e dataType);
};
#endif // library file header guard endif

View File

@ -10,12 +10,11 @@
[env]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
;platform = https://github.com/platformio/platform-raspberrypi.git
framework = arduino
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
upload_port = /dev/cu.usbmodem11301
monitor_port = /dev/cu.usbmodem11301
upload_port = /dev/cu.usbmodem11101
monitor_port = /dev/cu.usbmodem11101
extra_scripts = post:scripts/extra_script.py
monitor_speed = 256000
@ -24,9 +23,7 @@ board = pico
lib_deps =
powerbroker2/SafeString@^4.1.27
adafruit/Adafruit NeoPixel@^1.11.0
adafruit/Adafruit MCP4725@^2.0.0
adafruit/Adafruit INA219@^1.2.1
robtillaart/MCP4725@^0.3.5
robtillaart/INA219@^0.1.3
bblanchon/ArduinoJson@^6.21.2
arduino-libraries/Arduino_JSON@^0.2.0

View File

@ -73,7 +73,7 @@ void rainbowy(int saturation, int brightness, int wait)
// saturation and value (brightness) (both 0-255, similar to the
// ColorHSV() function, default 255), and a true/false flag for whether
// to apply gamma correction to provide 'truer' colors (default true).
leds.rainbow(firstPixelHue, 1, saturation, 255, true);
leds.rainbow(firstPixelHue, 1, saturation, brightness, true);
// Above line is equivalent to:
// strip.rainbow(firstPixelHue, 1, 255, 255, true);
leds.show(); // Update strip with new contents

View File

@ -16,8 +16,12 @@
#include "ADCInput.h"
#include "pico/cyw43_arch.h"
#include "mcp4725.hpp"
#define DAC_RESOLUTION 9
float freq[3] = {1, 1, 0};
uint32_t period[3] = {0, 0, 0};
uint32_t halvePeriod[3] = {0, 0, 0};
@ -29,8 +33,12 @@ uint32_t halvePeriod[3] = {0, 0, 0};
// r = random
char mode[3] = {'z', 'z', 'z'};
MCP4725 dac0_5V(0x60, &Wire);
MCP4725 dac1_8V(0x63, &Wire);
MCP4725_PICO dac0_5V(5.0);
MCP4725_PICO dac1_8V(8.0);
INA219 INA0(0x40);
INA219 INA1(0x41);
@ -85,14 +93,14 @@ adc_gpio_init(ADC2_PIN);
void initDAC(void)
{
//Wire.begin();
dac1_8V.begin(MCP4725A1_Addr_A01, i2c0, 3000, 4,5);
dac0_5V.begin(MCP4725A0_Addr_A00, i2c0, 3000, 4,5);
dac1_8V.begin(4, 5);
dac0_5V.begin(4, 5);
//
Wire.begin();
dac0_5V.setValue(0);
dac1_8V.setValue(2047);
dac0_5V.setVoltage(4.0);
dac1_8V.setVoltage(1.0);
}
@ -139,82 +147,84 @@ void dacSine(int resolution)
case 0 ... 5:
for (i = 0; i < 32; i++)
{
dac1_8V.setValue(DACLookup_FullSine_5Bit[i]);
dac1_8V.setInputCode(DACLookup_FullSine_5Bit[i]);
}
break;
case 6:
for (i = 0; i < 64; i++)
{
dac1_8V.setValue(DACLookup_FullSine_6Bit[i]);
dac1_8V.setInputCode(DACLookup_FullSine_6Bit[i]);
}
break;
case 7:
for (i = 0; i < 128; i++)
{
dac1_8V.setValue(DACLookup_FullSine_7Bit[i]);
dac1_8V.setInputCode(DACLookup_FullSine_7Bit[i]);
}
break;
case 8:
for (i = 0; i < 256; i++)
{
dac1_8V.setValue(DACLookup_FullSine_8Bit[i]);
dac1_8V.setInputCode(DACLookup_FullSine_8Bit[i]);
}
break;
case 9 ... 12:
for (i = 0; i < 512; i++)
{
dac1_8V.setValue(DACLookup_FullSine_9Bit[i]);
dac1_8V.setInputCode(DACLookup_FullSine_9Bit[i]);
}
break;
}
}
void setDac0_5V(float voltage)
{
uint16_t value = voltage * 819;
//uint16_t value = voltage * 819;
// float vPerBit = 5 / 4096;
// uint32_t voltage = value * vPerBit;
Serial.print("dac0_5V voltage: ");
Serial.print(voltage);
Serial.print("\tvalue: ");
//Serial.print("dac0_5V voltage: ");
//Serial.print(voltage);
//Serial.print("\tvalue: ");
Serial.println(value);
//Serial.println(value);
dac0_5V.setValue(value);
dac0_5V.setVoltage(voltage);
// if (dac1_8V.setValue(value, 100000) == false)
// if (dac1_8V.setVoltage(value, 100000) == false)
//{
// Serial.println("dac1_8V.setValue() failed");
// Serial.println("dac1_8V.setVoltage() failed");
// }
}
void setDac1_8V(float voltage)
{
uint16_t value = voltage * 276;
//uint16_t value = voltage * 276;
// float vPerBit = 5 / 4096;
if (value >= 4095)
{
value = 4095;
}
//if (value >= 4095)
//{
//value = 4095;
// }
// uint32_t voltage = value * vPerBit;
Serial.print("dac1 +-8V voltage: ");
Serial.print(voltage / 2);
Serial.print("\tvalue: ");
//Serial.print("dac1 +-8V voltage: ");
//Serial.print(voltage / 2);
//Serial.print("\tvalue: ");
Serial.println(value);
//Serial.println(value);
dac1_8V.setValue(value);
dac1_8V.setVoltage(voltage);
// if (dac1_8V.setValue(value, 100000) == false)
// if (dac1_8V.setVoltage(value, 100000) == false)
//{
// Serial.println("dac1_8V.setValue() failed");
// Serial.println("dac1_8V.setVoltage() failed");
// }
}
@ -314,8 +324,11 @@ void waveGen(void)
refillTable(amplitude[0], offset[0] + calib[0], 0);
refillTable(amplitude[1], offset[1] + calib[1], 1);
dac0_5V.setValue(1);
dac1_8V.setValue(offset[1] + calib[1]);
if (dac0_5V.setVoltage(0.0) == false)
{
Serial.println("dac0_5V.setVoltage() failed");
}
dac1_8V.setInputCode(offset[1] + calib[1]);
Serial.println("\n\r\t\t\t\t waveGen\t\n\n\r\toptions\t\t\twaves\t\t\tadjust frequency\n\r");
Serial.println("\t5/0 = dac 0 0-5V (togg)\tq = square\t\t+ = frequency++\n\r");
@ -405,7 +418,7 @@ chars += Serial.print(adc0Reading);
case '8':
if (activeDac == 0)
{
dac0_5V.setValue(0);
dac0_5V.setVoltage(0);
}
if (activeDac != 3)
@ -415,14 +428,14 @@ chars += Serial.print(adc0Reading);
if (dacOn[activeDac] == 0)
{
dac1_8V.setValue(amplitude[activeDac]);
dac1_8V.setInputCode(amplitude[activeDac]);
}
break;
case '5':
if (activeDac == 1)
{
dac1_8V.setValue(amplitude[activeDac]);
dac1_8V.setInputCode(amplitude[activeDac]);
}
if (activeDac != 3)
@ -431,7 +444,7 @@ chars += Serial.print(adc0Reading);
activeDac = 0;
if (dacOn[activeDac] == 0)
{
dac0_5V.setValue(0);
dac0_5V.setVoltage(0);
}
break;
case 'c':
@ -533,54 +546,54 @@ chars += Serial.print(adc0Reading);
if (t < halvePeriod[activeDac])
{
if (activeDac == 0 && dacOn[activeDac] == 1)
dac0_5V.setValue(amplitude[activeDac]);
dac0_5V.setInputCode(amplitude[activeDac]);
else if (activeDac == 1 && dacOn[activeDac] == 1)
dac1_8V.setValue(amplitude[activeDac]);
dac1_8V.setInputCode(amplitude[activeDac]);
}
else
{
if (activeDac == 0 && dacOn[activeDac] == 1)
dac0_5V.setValue(offset[activeDac]);
dac0_5V.setInputCode(offset[activeDac]);
else if (activeDac == 1 && dacOn[activeDac] == 1)
dac1_8V.setValue(offset[activeDac]);
dac1_8V.setInputCode(offset[activeDac]);
}
break;
case 'w':
if (activeDac == 0 && dacOn[activeDac] == 1)
dac0_5V.setValue(t * amplitude[activeDac] / period[activeDac]);
dac0_5V.setInputCode(t * amplitude[activeDac] / period[activeDac]);
else if (activeDac == 1 && dacOn[activeDac] == 1)
dac1_8V.setValue(t * amplitude[activeDac] / period[activeDac]);
dac1_8V.setInputCode(t * amplitude[activeDac] / period[activeDac]);
break;
case 't':
if (activeDac == 0 && dacOn[activeDac] == 1)
{
if (t < halvePeriod[activeDac])
dac0_5V.setValue(((t * amplitude[activeDac]) / halvePeriod[activeDac] )+ offset[activeDac]);
dac0_5V.setInputCode(((t * amplitude[activeDac]) / halvePeriod[activeDac] )+ offset[activeDac]);
else
dac0_5V.setValue((((period[activeDac] - t) * (amplitude[activeDac]) / halvePeriod[activeDac])+offset[activeDac]));
dac0_5V.setInputCode((((period[activeDac] - t) * (amplitude[activeDac]) / halvePeriod[activeDac])+offset[activeDac]));
}
else if (activeDac == 1 && dacOn[activeDac] == 1)
{
if (t < halvePeriod[activeDac])
dac1_8V.setValue(t * amplitude[activeDac] / halvePeriod[activeDac]);
dac1_8V.setInputCode(t * amplitude[activeDac] / halvePeriod[activeDac]);
else
dac1_8V.setValue((period[activeDac] - t) * amplitude[activeDac] / halvePeriod[activeDac]);
dac1_8V.setInputCode((period[activeDac] - t) * amplitude[activeDac] / halvePeriod[activeDac]);
}
break;
case 'r':
if (activeDac == 0 && dacOn[activeDac] == 1)
dac0_5V.setValue(random(amplitude[activeDac]) + offset[activeDac]);
dac0_5V.setInputCode(random(amplitude[activeDac]) + offset[activeDac]);
else if (activeDac == 1 && dacOn[activeDac] == 1)
{
dac1_8V.setValue(random(amplitude[activeDac]) + offset[activeDac]);
dac1_8V.setInputCode(random(amplitude[activeDac]) + offset[activeDac]);
}
break;
case 'z': // zero
if (activeDac == 0)
dac0_5V.setValue(0);
dac0_5V.setVoltage(0);
else if (activeDac == 1)
dac1_8V.setValue(offset[activeDac]);
dac1_8V.setInputCode(offset[activeDac]);
break;
case 'h': // high
Serial.println("\n\r\t\t\t\t waveGen\t\n\n\r\toptions\t\t\twaves\t\t\tadjust frequency\n\r");
@ -593,7 +606,7 @@ chars += Serial.print(adc0Reading);
mode[activeDac] = mode[2];
break;
case 'm': // mid
// dac1_8V.setValue(2047);
// dac1_8V.setInputCode(2047);
break;
case 'a':
{
@ -868,15 +881,15 @@ chars += Serial.print(adc0Reading);
case 's':
// reference
// float f = ((PI * 2) * t)/period;
// dac1_8V.setValue(2047 + 2047 * sin(f));
// dac1_8V.setInputCode(2047 + 2047 * sin(f));
//
if (mode[activeDac] != 'v')
{
int idx = (360 * t) / period[activeDac];
if (activeDac == 0 && dacOn[activeDac] == 1)
dac0_5V.setValue(sine0[idx]); // lookuptable
dac0_5V.setInputCode(sine0[idx]); // lookuptable
else if (activeDac == 1 && dacOn[activeDac] == 1)
dac1_8V.setValue(sine1[idx]); // lookuptable
dac1_8V.setInputCode(sine1[idx]); // lookuptable
}
break;
}

View File

@ -1,10 +1,11 @@
#ifndef PERIPHERALS_H
#define PERIPHERALS_H
//#include "Adafruit_MCP4725.h"
#include "MCP4725.h"
//#include "MCP4725.h"
#include <Arduino.h>
#include "INA219.h"
#include "Wire.h"
#include <Wire.h>
void initINA219(void);

View File

@ -10,16 +10,11 @@
// #include "CH446Q.h"
#include "Peripherals.h"
#include <Wire.h>
#include <Adafruit_MCP4725.h>
// #include <EEPROM.h>
// #include "ArduinoStuff.h"
#ifdef EEPROMSTUFF
#include <EEPROM.h>
#endif
@ -114,7 +109,7 @@ debugFlagInit();
// delay(20);
//}
// rainbowy(255,253,100);
// parseWokwiFileToNodeFile();
// openNodeFile();
// while(1);
@ -140,7 +135,7 @@ void loop()
// initArduino();
//
//rainbowy(255,145,100);
menu:
// arduinoPrint();