Categories
Statistics
Flag Counter
Since 08.08.2014
Counts only, if "DNT = disabled".

Your IP is 44.213.60.33
ec2-44-213-60-33.compute-1.a
Info
Valid HTML 4.01 Transitional Creative Commons Lizenzvertrag
rss
เราจะทำแบบวิศวกรผู้ยิ่งใหญ่
We love the King
15. July 2024
Your valuable opinion :
5 stars

Avg. 6 from 9 votes.



Arduino-Sungmod.php    15149 Bytes    09-06-2024 12:25:30


Arduino/Genuino "Sungmod"


A high Voltage Power Supply for Photodiodes






The prototype


HV ระวัง ไฟฟ้า แรง สูง !

You have been warned ...




✈ Motivation




Some Photodiodes in our lab used for e.g. a Photon Counter need a High Voltage Bias. This design uses two identical power transformers (connected back to back) to generate a mains-isolated high voltage of approx. 300 V. This method was the preferred solution of my (now retired) colleague, Mr. Paul Studerus. So consider this design somehow as a tribute to yet another engineer with "Guru-Status", crossing my professional career.




✈ The Design





The Block Diagram of the "Sungmod"


The design is straightforward. As the dissipated power is very small, we used a linear regulator (IRF740/840). The High Voltage (approx. 300V) is generated with two identical transformers, were the low voltage side is connected back to back.

The Setpoint is generated by an AD5667R (Dual, 16-Bit nanoDACs® with 5 ppm/°C On-Chip Reference, I2C® Interface). A single Opamp (OPA140) controls the output voltage therefore, that it pulls the gate of the main transistor down. It is pulled up by a pnp transistor injecting approx. 1 mA into the gate.

The current is measured with a 1 Ω shunt. The voltage drop across it is amplified with a LT1789CS8-1 (Micropower, Single Supply Rail-to-Rail Output Instrumentation Amplifier) and then fed to an analog input of the Arduino. One could realise a current limit by that in software, but the prototype hasn't got that feature.



A look inside. And yes, the interesting components are below the ribbon cable :-)




✈ Downloads








✈ Test Sketch for Arduino/Genuino Nano



Double click on code to select ...

/* ////////////////////////////////////////////////////////////////// 

ARDUINO/Genuino Nano Sketch for Sungmod
https://www.changpuak.ch/electronics/Arduino-Sungmod.php
A High Voltage Power Supply for Photodiodes
Software Version 5.1
28.07.2019, Alexander Sse Frank
USEFUL:
learn.adafruit.com/adafruit-gfx-graphics-library/graphics-primitives

////////////////////////////////////////////////////////////////// */

#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
#include <Wire.h>

// DISPLAY

#define OLED_MOSI  11
#define OLED_CLK   12
#define OLED_DC    9
#define OLED_CS    8
#define OLED_RESET 10




Adafruit_SH1106 display(OLED_MOSI,OLED_CLK,OLED_DC,OLED_RESET,OLED_CS);

#if (SH1106_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SH1106.h!");
#endif

// ROTARY ENCODER

const int RotaryEncoder1 = 4 ;   // PRESSED
const int RotaryEncoder2 = 2 ;
const int RotaryEncoder3 = 3 ;

volatile bool LEFT = false ;
volatile bool RIGHT = false ;
volatile bool READY = true ;

// /////////////////////////////////////////////////////////////////////
// SUBROUTINES DAC AD5667R
// /////////////////////////////////////////////////////////////////////

// Pin 6 = ADDR is on GND >>> A0 = 1, A1 = 1
// Only VOUTA is used

const byte DAC_ADR = 0x0F ;
const float VoltFactor = 206.221 ;
const float MaxVolt = 270.000 ;
const float MinVolt = 0.000 ;
float SetVolt = 259.0 ;

void WriteDAC(byte cmd, unsigned int payload) 
{
byte lsb = payload & 0xFF ;
byte msb = (payload & 0xFF00) >> 8 ;
Wire.beginTransmission(DAC_ADR) ;  
Wire.write(cmd) ;   
Wire.write(msb);  
Wire.write(lsb);                  
Wire.endTransmission();
}

void UpdateVolt() 
{
unsigned int Setpoint = 0x0000 ;
Setpoint = (int)(SetVolt * VoltFactor) ; 
WriteDAC(0x10, Setpoint) ; 
Serial.println(Setpoint,DEC) ;
}



// /////////////////////////////////////////////////////////////////////
// D I S P L A Y
// /////////////////////////////////////////////////////////////////////

float Current = 0.0 ;
const int CurrentPin = A6 ;
int CursorPos = 2 ;  
int CurrBuff[32] ;      // STORES RAW VALUE
int CurrBuffPoint = 0 ;
const int MaxCurrBuffPoint = 31 ;
const float CurrentMuly = 5.0 / 1023.0 ; 


void ReadCurrent()
{
int CurrBuffSum = 0 ;

CurrBuffPoint += 1 ;
if(CurrBuffPoint > MaxCurrBuffPoint) CurrBuffPoint = 0 ;
CurrBuff[CurrBuffPoint] = analogRead(CurrentPin) ;
CurrBuffSum = 0 ;
for(int i = 0 ; i < MaxCurrBuffPoint; i++)
{
CurrBuffSum += CurrBuff[i] ;
}
Current = CurrentMuly * (float)CurrBuffSum / MaxCurrBuffPoint ; 
Serial.println(Current,3); 
}


void UpdateDisplay()
{
ReadCurrent() ;
display.clearDisplay() ;
display.setTextSize(1) ;
display.setTextColor(WHITE) ;
display.setCursor(0,0); display.print("*****  SUNGMOD  *****") ;
display.drawLine(0, 12, 128, 12, WHITE) ;

display.setTextSize(2) ;
// VOLTAGE
display.setCursor(10, 21);
if (SetVolt < 99.999) display.print(" ");
if (SetVolt < 9.999) display.print(" ");
display.print(SetVolt,3);
display.setCursor(104, 21);
display.print("V");
// CURSOR
display.setCursor(10, 26);
if(CursorPos == 1) display.print(" ");
if(CursorPos == 2) display.print("  ");
if(CursorPos == 3) display.print("    ");
if(CursorPos == 4) display.print("     ");
if(CursorPos == 5) display.print("      ");
display.print("_");
// CURRENT
display.setCursor(10, 45);
if(Current < 99.999) display.print(" ") ;
if(Current < 9.9999) display.print(" ") ;
display.print(Current,3);  
display.setCursor(104, 45);
display.print("mA");

display.display() ;
}



// /////////////////////////////////////////////////////////////////////
// S E T U P
// /////////////////////////////////////////////////////////////////////


void setup() 
{
Serial.begin(115200);

Wire.begin() ;

pinMode(RotaryEncoder1, INPUT_PULLUP) ;
pinMode(RotaryEncoder2, INPUT_PULLUP) ;
pinMode(RotaryEncoder3, INPUT_PULLUP) ;

// YELLOW
attachInterrupt(digitalPinToInterrupt(RotaryEncoder2), 
RotaryEncoderISR2, FALLING) ;
// GREEN
attachInterrupt(digitalPinToInterrupt(RotaryEncoder3), 
RotaryEncoderISR3, FALLING) ;

// INIT OLED
display.begin(SH1106_SWITCHCAPVCC) ;

// SHOW STARTUP SCREEN
display.clearDisplay() ;
display.setTextSize(1) ;
display.setTextColor(WHITE) ;
display.setCursor(0,0);
display.println("*****  SUNGMOD  *****") ;
display.drawLine(0, 12, 128, 12, WHITE) ;
display.setTextSize(1) ;
display.setCursor(0,21) ;
display.println("A HIGH VOLTAGE") ;
display.setCursor(0,33) ;
display.println("POWER SUPPLY FOR") ;
display.setCursor(0,45) ;
display.println("PHOTODIODES.") ;
display.setCursor(0,57) ;
display.println("BUILT 23.10.2021") ;
display.display() ;


// DAC AD5667R
// RESET ALL
WriteDAC(0x28, 0x0001) ;
// POWER UP CHANNEL A
WriteDAC(0x20, 0x0001) ;
// SETUP LDAC PIN = BOTH DISABLED
WriteDAC(0x30, 0x0003) ;
// SWITCH ON REFERENCE
WriteDAC(0x38, 0x0001) ;

delay(999) ;

UpdateVolt() ;
UpdateDisplay() ;
}


// /////////////////////////////////////////////////////////////////////
// M A I N 
// /////////////////////////////////////////////////////////////////////

void loop() 
{
// KEY ROTATED ?
// //////////////////////////////////
if(LEFT)
// //////////////////////////////////
{
switch (CursorPos)
{
  case 0 : 
	if((SetVolt - 100.0) >= MinVolt) SetVolt-=100.0 ;
	break ;
  case 1 : 
	if((SetVolt - 10.0) >= MinVolt) SetVolt-=10.0 ;
	break ;
  case 2 : 
	if((SetVolt - 1.0) >= MinVolt) SetVolt-=1.0 ;
	break ;
  case 3 : 
	if((SetVolt - 0.1) >= MinVolt) SetVolt-=0.1 ;
	break ;       
}  
UpdateVolt() ; 
delay(59) ;
READY = true ;
LEFT = false ;
RIGHT = false ;
}


// //////////////////////////////////
if(RIGHT)
// //////////////////////////////////
{    
switch (CursorPos)
{
  case 0 : 
	if((SetVolt + 100.0) <= MaxVolt) SetVolt+=100.0 ;
	break ;
  case 1 : 
	if((SetVolt + 10.0) <= MaxVolt) SetVolt+=10.0 ;
	break ;
  case 2 : 
	if((SetVolt + 1.0) <= MaxVolt) SetVolt+=1.0 ;
	break ;
  case 3 : 
	if((SetVolt + 0.1) <= MaxVolt) SetVolt+=0.1 ;
	break ;       
}
UpdateVolt() ;
delay(59) ;
READY = true ;
LEFT = false ;
RIGHT = false ;
}


// //////////////////////////////////
// KEY PRESSED ?
// //////////////////////////////////
if(!digitalRead(RotaryEncoder1)) 
{
CursorPos += 1 ;
if(CursorPos > 5) CursorPos = 0 ;
delay(199) ;
}    


UpdateDisplay() ;
delay(59) ;


}


// /////////////////////////////////////////////////////////////////////
// INTERRUPT SERVICE ROUTINES
// /////////////////////////////////////////////////////////////////////

void RotaryEncoderISR2()
{
// YELLOW
if(READY)
{
LEFT = false ;
RIGHT = false ;
byte autre = digitalRead(RotaryEncoder3) ;
if (autre > 0) RIGHT = true ;
if (autre < 1) LEFT = true ;
}
}

void RotaryEncoderISR3()
{
// GREEN
if(READY)
{
LEFT = false ;
RIGHT = false ;
byte autre = digitalRead(RotaryEncoder2) ;
if (autre > 0) LEFT = true ;
if (autre < 1) RIGHT = true ;
}
}


// /////////////////////////////////////////////////////////////////////
// END OF FILE.
// /////////////////////////////////////////////////////////////////////




✈ Performance





Voltage Drift @ 259.0 V, current drawn was 1.0 mA. First 9 hours after Power On.




A note on Arduino Nano :
We first used the Nano Every, but it turned out, that the 5 V regulator (MPM3610) was somehow unable to supply the AD5667R. Switching to the original Nano (LM1117IMPX-5.0) solved this problem. (Without redesigning the board).




✈ Share your thoughts



The webmaster does not read these comments regularely. Urgent questions should be send via email. Ads or links to completely uncorrelated things will be removed.


Your Browser says that you allow tracking. Mayst we suggest that you check that DNT thing ?

 
t1 = 6577 d

t2 = 188 ms

★ ★ ★  Copyright © 2006 - 2024 by changpuak.ch  ★ ★ ★

Impressum