Last active
March 22, 2021 04:38
-
-
Save Electronza/470d485ba449b8337a338c090ccec7aa to your computer and use it in GitHub Desktop.
VREG Click: adjustable power supply with Arduino Uno
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Project page | |
# https://medium.com/electronza/vreg-click-adjustable-power-supply-with-arduino-uno-2c61422e17bd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SPI.h> | |
// PIN definitions for VREG click | |
// uses mikroBUS socket #1 | |
#define DAC_CS 10 // chip select for MCP4921 DAC | |
#define ADC_CS A0 // chip select for MCP3204 ADC | |
#define OUT_PIN 6 // output on/off | |
// Vreg Click uses SPI communication (pins 11, 12, 13) | |
// Used to read voltages | |
float Vin; | |
float Vsense; | |
float Vout; | |
unsigned int Vtmp; // stores ADC results | |
int incomingByte = -1; // stores incoming serial data | |
// Variables used for DAC | |
int setDAC = 909; // start with 3.3V output | |
int maxDAC = 3090; | |
int minDAC = 227; | |
// Preset voltages. Be sure to give values in the {minDAC, ... , maxDAC] interval | |
int vset1 = 600; // 3.3V | |
int vset2 = 909; // 5V | |
int vset3 = 1636; // 9V | |
int vset4 = 2181; // 12V | |
int vset5 = 2727; // 15V | |
// Output status | |
bool output_status = false; | |
// Used to update the serial output | |
// Take a look at "Blink without Delay" example. It helps! | |
unsigned long previousMillis = 0; // will store last update time | |
const long interval = 500; // update interval | |
void setup() { | |
// Set required pins as output | |
pinMode(DAC_CS, OUTPUT); | |
pinMode(ADC_CS, OUTPUT); | |
pinMode(OUT_PIN, OUTPUT); | |
// set CD pins on HIGH | |
digitalWrite(DAC_CS, HIGH); | |
digitalWrite(ADC_CS, HIGH);; | |
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps | |
SPI.begin(); | |
outputOFF(); // output is off when we start | |
DAC_Output(setDAC); // start with 3.3V output | |
// Now some info | |
Serial.println ("VREG Click Arduino adjustable power supply"); | |
Serial.println (" "); | |
Serial.println ("Send + or = to increase voltage"); | |
Serial.println ("Send - or _ to decrease voltage"); | |
Serial.println ("Send 0 or ) for a fine increase of voltage"); | |
Serial.println ("Send 9 or ( for a fine decrease of voltage"); | |
Serial.println ("Send 1 for 3.3V output"); | |
Serial.println ("Send 2 for 5V output"); | |
Serial.println ("Send 3 for 9V output"); | |
Serial.println ("Send 4 for 12V output"); | |
Serial.println ("Send 5 for 15V output"); | |
Serial.println ("Send SPACE to turn output ON or OFF"); | |
Serial.println (" "); | |
Serial.println ("Send any key to start"); | |
Serial.println (" "); | |
while(Serial.available() == 0){} | |
} | |
void loop() { | |
// Receive data from terminal | |
if (Serial.available()) { | |
incomingByte = Serial.read(); | |
// read the incoming byte: | |
if (incomingByte >= 0) // incomingByte = -1 if no data is received | |
{ | |
// Are we increasing the voltage? | |
if ((incomingByte == 0x2B) | (incomingByte == 0x3D)) // 0x2B = "+", 0x3D = "=" | |
{ | |
setDAC = setDAC + 90; // increase voltage | |
} | |
if ((incomingByte == 0x30) | (incomingByte == 0x29)) // 0x30 = "0", 0x29 = ")" | |
{ | |
setDAC = setDAC + 1; // fine increase voltage | |
} | |
// check for max value | |
if (setDAC > maxDAC) | |
{ | |
setDAC = maxDAC; | |
} | |
// Are we decreasing the voltage? | |
if ((incomingByte == 0x2D) | (incomingByte == 0x5F)) // 0x2D = "-", 0x5F = "_" | |
{ | |
setDAC = setDAC - 90; // decrease voltage | |
} | |
if ((incomingByte == 0x39) | (incomingByte == 0x28)) // 0x39 = "9", 0x28 = "(" | |
{ | |
setDAC = setDAC - 1; // fine decrease voltage | |
} | |
// check for min value | |
if (setDAC < minDAC) | |
{ | |
setDAC = minDAC; | |
} | |
// Preset values | |
if ((incomingByte == 0x31) | (incomingByte == 0x21)) // 0x31 = "1", 0x21 = "!" | |
{ | |
setDAC = vset1; | |
} | |
if ((incomingByte == 0x32) | (incomingByte == 0x40)) // 0x32 = "2", 0x40 = "@" | |
{ | |
setDAC = vset2; | |
} | |
if ((incomingByte == 0x33) | (incomingByte == 0x23)) // 0x33 = "3", 0x23 = "#" | |
{ | |
setDAC = vset3; | |
} | |
if ((incomingByte == 0x34) | (incomingByte == 0x24)) // 0x34 = "4", 0x24 = "$" | |
{ | |
setDAC = vset4; | |
} | |
if ((incomingByte == 0x35) | (incomingByte == 0x25)) // 0x35 = "5", 0x25 = "%" | |
{ | |
setDAC = vset5; | |
} | |
// update DAC value | |
DAC_Output(setDAC); | |
// output ON/OFF | |
if (incomingByte == 0x20) // 0x20 = " " | |
{ | |
// toggle output | |
output_status = !output_status; | |
if (output_status == 0){ | |
outputOFF(); | |
} | |
else{ | |
outputON(); | |
} | |
} | |
// all OK, we finished parsing the serial data | |
} | |
} | |
UpdateSerial(); | |
} | |
void UpdateSerial(void) | |
{ | |
// read ADC values and update serial terminal every 500ms | |
// I used millis() to implement the delay as it does not | |
// interfere with Serial.read(); | |
// Update the serial terminal | |
unsigned long currentMillis = millis(); | |
if (currentMillis - previousMillis >= interval) { | |
// save the last time you blinked the LED | |
previousMillis = currentMillis; | |
// send update to serial monitor | |
Vtmp = getADC(2); | |
Vin = Vtmp * 0.0055; | |
Serial.print ("Vin = "); | |
Serial.print (Vin); | |
Vtmp = getADC(0); | |
Vsense = Vtmp * 0.0055; | |
Serial.print ("; Vsense = "); | |
Serial.print (Vsense); | |
if (output_status == 0){ | |
Serial.println ("; Output Off"); | |
} | |
else{ | |
Vtmp = getADC(1); | |
Vout = Vtmp * 0.0055; | |
Serial.print ("; Vout = "); | |
Serial.println (Vout); | |
} | |
} | |
} | |
// DAC increments (0..4095) --> output voltage (0..Vref) | |
// 16 bit writes, first four bits are config bits: | |
// bit 15 A/B: DACA or DACB Select bit (1 = Write to DACB, 0 = Write to DACA) | |
// bit 14 BUF: VREF Input Buffer Control bit (1 = Buffered, 0 = Unbuffered) | |
// bit 13 GA: Output Gain Select bit | |
// 1 = 1x (VOUT = VREF * D/4096), 0 = 2x (VOUT = 2 * VREF * D/4096) | |
// bit 12 SHDN: Output Power Down Control bit | |
// 1 = Output Power Down Control bit | |
// 0 = Output buffer disabled, Output is high impedance | |
// bits 11:0 DATA BITS | |
void DAC_Output(unsigned int valueDAC) | |
{ | |
char tmp; | |
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); | |
// Select DAC chip | |
digitalWrite(DAC_CS, LOW); | |
// Send High Byte | |
tmp = (valueDAC >> 8) & 0x0F; // Store valueDAC[11..8] to tmp[3..0] | |
tmp |= 0x30; // GAIN = X1, SHDN = 1 | |
SPI.transfer(tmp); | |
// Send Low Byte | |
tmp = valueDAC; // Store valueDAC[7..0] to tmp[7..0] | |
SPI.transfer(tmp); | |
// Deselect DAC chip | |
digitalWrite(DAC_CS, HIGH); | |
SPI.endTransaction(); | |
} | |
// Get ADC values, returns 0..4095 | |
unsigned int getADC(unsigned short channel) | |
{ | |
unsigned int tmp; | |
SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE0)); | |
// Select ACC chip | |
digitalWrite(ADC_CS, LOW); | |
SPI.transfer(0x06); // SPI communication using 8-bit segments | |
channel = channel << 6; // Bits 7 & 6 define ADC input | |
tmp = SPI.transfer(channel) & 0x0F; // Get first 8 bits of ADC value | |
tmp = tmp << 8; // Shift ADC value by 8 | |
tmp = tmp | SPI.transfer(0); // Get remaining 4 bits of ADC value | |
digitalWrite(ADC_CS, HIGH); // Deselect MCP3204 | |
return tmp; // Returns 12-bit ADC value | |
} | |
void outputON(void) | |
{ | |
digitalWrite(OUT_PIN, HIGH); | |
} | |
void outputOFF(void) | |
{ | |
digitalWrite(OUT_PIN, LOW); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment