Author Archives: admin

Kepco JQE75-1.5M PSU refurbishment – Part 2

Published by:

So I continue my refurbishment of the Kepco JQE75-1.5M PSU.

My LED displays arrived from Ebay so I decided it’s time to fit them, and time to replaced the neon power indicator with an LED.

 

I could not find a stable voltage (as in, not changing when adjusting the current/voltage pot) so I opted to find an AC voltage either on the board or on the transformer itself.

After 2 attempts I found an unused 24Vac winding on the transformer and hooked up the following circuit to the LED display and power LED which replaces the neon bulb.

 

mod

(Note: there is a 330uF 50V electrolytic reservoir cap across the DC output voltage I forgot to draw in)

 

This seems to work fine, now I just need to fit an IEC connector and a bezel for the LED display on the front panel.

2016-03-19 01.08.00

How I reverse engineer digital circuits

Published by:

2016-03-12 19.56.14

It’s been a while since I’ve posted to my blog, but here is a video I just uploaded showing how I reverse engineer digital circuits.

I’ve been doing this sort of thing for as long as I can remember and I find it very relaxing at times. Nothing better than throwing some nice music on and doing a bit of reverse engineering.

I was recently given a dot matrix LED display by a friend and decided to reverse engineer it so we both can run them, he still has one of his own.

There is a damaged chip on the board which meant that some of the displays didn’t display their 2 bottom rows but I will be tackling this issue in a later video. I will also be transferring the control to a PIC instead of the Arduino as it was not fast enough to get a good refresh rate, and this is without any external communication facilities being addressed.

Here is the video:

The arduino sketch can be downloaded here

and the Design Spark schematic file can be found here

the PDF of this file can be found here

*There are a few parts not finished in the schematic, but there is enough to provide functional detail.

I hope you enjoy the video, I will eventually follow it up with the repairs and the porting to PIC.

bye for now!

Kepco JQE75-1.5M PSU refurbishment – Part 1

Published by:

I found myself some PSU’s at a flee market a few weeks back and decided to pull out the matching pair of 75V PSU’s for some inspection. Much to my delight, they both appear to work fine.

The only issues with them is the neon power indicators are not working (or barely working), and the voltage/current multiply switches for the analogue movements are crusty. And not to mention a non-standard power connector on the rear. These will all be replaced and updated in future videos.

I have decided to replace the analogue meters with LED modules (just waiting for them to be shipped from China on the slow boat) then I will hook them into to sense the output terminals and find a way to recess it in places of the old meters.

For the power indicator, I will find a voltage rail inside the PSU (most likely an opamp rail) and fit an LED in place of the neon lamp.

Please keep tuned for more!

You can subscribe to my YouTube channel to get updates on my progress too.

PSU Project #11 – Prototype and Calibration

Published by:

It’s been a while since I’ve released a video for this series, but I have been doing final tests for the term at college and was a little overwhelmed. But I did my last test yesterday and decided it was time to do an update.

 

The schematic as PDF can be found here: PSU – Schematic

As promised in the video, here is a flowchart showing how the software currently works. This is the basic idea of what goes on.

Do note that the Volts and Current pots on the front of the case do not directly set the current and voltage limits, rather they are read by the Arduino via the ADC and scaled and then that is outputted via the DAC to the actually regulation circuitry. This leaves the possibility of having the push-buttons setting the Voltage and Current instead.

flowchart

Here is the Arduino code used in this episode, I will be cleaning it up for the final version:

#include "SPI.h"
#include <LiquidCrystal.h>
#define SW1 18 // Rightmost button
#define SW2 17
#define SW3 16
#define SW4 15
#define SW5 14 // Leftmost button
#define ADC_CS 10 // ADC chip-select
#define DAC_CS 9 // DAC chip-select
#define LCD_D7 8 
#define LCD_D6 7
#define LCD_D5 6
#define LCD_D4 5
#define LCD_E 4
#define LCD_RS 3
//#define SPARE 2
#define vout_cal 0.0065651063;
#define iout_cal 0.001;
#define vin_cal 0.006092087;
#define iin_cal 0.001;
#define max_scount 100000 // Counts for screen update
unsigned int v_set,i_set,v_feedback,i_feedback;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
void setup() {
 //set pin modes 
 pinMode(DAC_CS, OUTPUT); 
 pinMode(ADC_CS, OUTPUT);
 
 pinMode(LCD_D7, OUTPUT); 
 pinMode(LCD_D6, OUTPUT); 
 pinMode(LCD_D5, OUTPUT); 
 pinMode(LCD_D4, OUTPUT); 
 pinMode(LCD_E, OUTPUT); 
 pinMode(LCD_RS, OUTPUT);
pinMode(SW1, INPUT); 
 pinMode(SW2, INPUT); 
 pinMode(SW3, INPUT); 
 pinMode(SW4, INPUT); 
 pinMode(SW5, INPUT);
 // disable all devices to start with 
 digitalWrite(ADC_CS, HIGH); 
 digitalWrite(DAC_CS, HIGH); 
 SPI.begin();
 Serial.begin(115200); 
 Serial.println("Ready.");
 // set up the LCD's number of columns and rows:
 lcd.begin(16, 2);
 // Print a message to the LCD.
 //lcd.print("hello, world!");
}
void set_dac(byte chan, unsigned int value,byte ga, byte shdn)
{
 byte b,c,conf;
 // ga : 0=2x (0-4096v), 1=1x (0-2.048v)
 // shdn : 0 = shutdown DAC channel, 1 = output available
 // [ A'/B , x , GA', SHDN', D11, D10, D9, D8 ]
 conf=(chan&0x01)<<7; // mask out channel number and shift it to bit 7
 conf=conf|(ga&0x01)<<5; // mask out gain select and shift it to bit 5 and or it to conf
 conf=conf|(shdn&0x01)<<4; // mask out shutdown select and shift it to bit 4 and or it to conf
 conf=conf|(value>>8); // or in the top nibble of value left in conf
 b = value; // bottom byte of value
 SPI.beginTransaction(SPISettings(15000000, MSBFIRST, SPI_MODE0));
 digitalWrite (DAC_CS, LOW); // enable DAC
 SPI.transfer(conf); // send configuration and top nibble of value
 SPI.transfer(b); // send bottom byte
 digitalWrite (DAC_CS, HIGH); // disable DAC
 SPI.endTransaction();
 
}
unsigned int get_adc(byte chan)
{
 unsigned int a,b,c,conf;
 conf=conf=((chan&0b00000111)<<1)|0b00110000; // create configuration byte
 SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
 digitalWrite (ADC_CS, LOW); // enable ADC
 SPI.transfer(conf); // send configuration byte
 b = SPI.transfer(0x00); // receive sign bit & top 4 bits 
 c = SPI.transfer(0x00); // receive lower 8 bits
 digitalWrite (ADC_CS, HIGH); // disable ADC
 SPI.endTransaction();
 b = b&0b00011111; // filter out unwanted stuff from high byte
 a = (b*0x100)+c; // convert 2 8-bit numbers into a single 16-bit number
 return(a);
}
unsigned int get_adc_avg(byte chan)
{
 long tempx = 0;
 byte ax = 0;
 for (ax=0;ax<20;ax++)
 {
 tempx+=get_adc(chan);
 }
 tempx/=20;
 return (tempx);
}
void update_screen()
{
 static float vout,vin,iout,iin;
 static char voutstr[15];
 static char ioutstr[15];
 static char vinstr[15];
 static char iinstr[15];
// 0.004884;
 vout = v_set*vout_cal;
 iout = i_set*iout_cal;
 vin = v_feedback*vin_cal;
 iin = i_feedback*iin_cal;
 
 dtostrf(vout, 5,2, voutstr);
 dtostrf(iout, 5,3, ioutstr);
 dtostrf(vin, 5,2, vinstr);
 dtostrf(iin, 5,3, iinstr);
if (digitalRead(SW5)==1)
 {
 lcd.setCursor(0, 0); lcd.print(v_set, DEC); lcd.print(" "); // for calibration
 lcd.setCursor(0, 1); lcd.print(i_set, DEC); lcd.print(" "); // for calibration
 lcd.setCursor(8, 0); lcd.print(v_feedback, DEC); lcd.print(" "); // for calibration
 lcd.setCursor(8, 1); lcd.print(i_feedback, DEC); lcd.print(" "); // for calibration
 }
 else
 {
 lcd.setCursor(0, 0); lcd.print(voutstr); lcd.print("V ");
 lcd.setCursor(0, 1); lcd.print(ioutstr); lcd.print("A ");
 lcd.setCursor(8, 0); lcd.print(vinstr); lcd.print("V "); 
 lcd.setCursor(8, 1); lcd.print(iinstr); lcd.print("A ");
 }
}
void loop() 
{
 unsigned long scount = max_scount+1;
 unsigned int xx = 0b100000;
unsigned int adc0;
 unsigned int adc1;
 unsigned int adc2;
 unsigned int adc3;
adc0 = get_adc_avg(0)/2;
 adc1 = get_adc_avg(1)/2;
 adc2 = get_adc_avg(2)/2;
 adc3 = get_adc_avg(3)/2;
 
 set_dac(0, (adc0),0, 1);
 set_dac(1, (adc1),0, 1);
v_set = adc0;
 i_set = adc1;
 v_feedback = adc2;
 i_feedback = adc3;
scount++;
 if (scount>max_scount)
 {
 scount=0;
 update_screen();
 }
 
}

PSU Project #10 – Current sensing and regulation

Published by:

In this video I will go over techniques of sensing current in the PSU circuit as well as explore the regulation of the current.

It’s been a while since my last episode, I have been busy with school work and I also needed to construct a variable dummy load in order to get this working.

We are nearing the end of the series. In the next video we will be putting the analogue side and the digital side together and having a look at it being completely driven from the DAC.

QSat Teardown – Part 2

Published by:

This is the 2nd part of the teardown of the QSat

In this video I do the actually capturing of some buttons on the IR receiver. We also analyze the LED data train and decode the way the screen is driven.

QSat Teardown – Part 1

Published by:

So I got another satellite receiver to tear down. This one is similar to the Viewsat VS2000 one I tore down previously, check the video

Just like the previous one I will be decoding the LED display driver, but unlike the previous one, I will be capturing the IR receiver data in hopes of using the remote control in a future project.

PSU Project #9 – Button and Matrix inputs

Published by:

Hi All,

sorry for the delay adding this to my website, I’ve been busy with college. I’ve just uploaded part 10 and realized that I didn’t update the webpage for 9, so here it is.

In this episode I will be briefly covering using the button inputs on the Arduino. I briefly go over debouncing and then I introduce using a matrix keypad to allow more buttons to be used.

Arduino code for debounced button input:

#include <LiquidCrystal.h>
#define button_5 6
#define button_4 7
#define button_3 8
#define button_2 9
#define button_1 10
#define hold_limit 15000
int temp=0,tempold=1;
int b1=0,b2=0,b3=0,b4=0,b5=0;
int bs1=0,bs2=0,bs3=0,bs4=0,bs5=0;
int bc1=0,bc2=0,bc3=0,bc4=0,bc5=0;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
 // set up the LCD's number of columns and rows:
 lcd.begin(16, 2);
 // Print a message to the LCD.
 lcd.print("hello, world!");
}
void loop() {
 // set the cursor to column 0, line 1
 // (note: line 1 is the second row, since counting begins with 0):
b1 = digitalRead(button_1);
 b2 = digitalRead(button_2);
 b3 = digitalRead(button_3);
 b4 = digitalRead(button_4);
 b5 = digitalRead(button_5);
//////////// Button 1 ///////////////
 if ((b1==1)&&(bs1==0))
 {
 temp = 0; bs1=1; bc1=0;
 }
 if ((b1==1)&&(bs1==1))
 {
 bc1++;
 if (bc1>hold_limit)
 {
 bs1=0; bc1=0;
 }
 }
 if ((b1==0)&&(bs1==1))
 {
 bs1=0;
 }
//////////// Button 2 ///////////////
 if ((b2==1)&&(bs2==0))
 {
 temp--; bs2=1; bc2=0;
 }
 if ((b2==1)&&(bs2==1))
 {
 bc2++;
 if (bc2>hold_limit)
 {
 bs2=0; bc2=0;
 }
 }
 if ((b2==0)&&(bs2==1))
 {
 bs2=0;
 }
//////////// Button 3 ///////////////
 if ((b3==1)&&(bs3==0))
 {
 temp++; bs3=1; bc3=0;
 }
 if ((b3==1)&&(bs3==1))
 {
 bc3++;
 if (bc3>hold_limit)
 {
 bs3=0; bc3=0;
 }
 }
 if ((b3==0)&&(bs3==1))
 {
 bs3=0;
 }
//////////// Button 4 ///////////////
 if ((b4==1)&&(bs4==0))
 {
 temp-=10; bs4=1; bc4=0;
 }
 if ((b4==1)&&(bs4==1))
 {
 bc4++;
 if (bc4>hold_limit)
 {
 bs4=0; bc4=0;
 }
 }
 if ((b4==0)&&(bs4==1))
 {
 bs4=0;
 }
//////////// Button 5 ///////////////
 if ((b5==1)&&(bs5==0))
 {
 temp+=10; bs5=1; bc5=0;
 }
 if ((b5==1)&&(bs5==1))
 {
 bc5++;
 if (bc5>hold_limit)
 {
 bs5=0; bc5=0;
 }
 }
 if ((b5==0)&&(bs5==1))
 {
 bs5=0;
 }
/////////////////////////////////////
 if (temp!=tempold)
 {
 lcd.setCursor(0, 1); lcd.print(" ");
 lcd.setCursor(0, 1); lcd.print(temp);
 tempold=temp;
 }
}

Open Workbench Logic Sniffer case – Part 4 (Finale)

Published by:

The expansion module finally arrived this morning 🙂 and the glue seems to be mostly set.

2015-10-22 19.52.56

Here is the expansion module lined up next to the OWLS board, now to fit the headers and find a cable.

Luckily I had an old short IDE cable around that works. It over hangs 4 pins either side but it works.

2015-10-22 20.22.13

Here is both board in place in their respective connectors.

2015-10-22 20.26.56

this is it with the case fully done up, the board sits on a slight angle but it is all nice and snug.

 

Now all left to do is hook up the cables and give it a test.

2015-10-22 20.34.05 2015-10-22 22.42.22

Here is it hooked up doing some reading of SPI traffic on the Arduino, note that 3 switches have been set on the panel, this is grounding the un-used pins to avoid phantom signals due to floating lines.

I had to mess around and update the firmware to make it recognize the extra 16 channels, the bootloader didn’t work so I had to use a PICKit3 to flash the OWLS’ PIC directly.

 

Below are a couple of captures from the SPI bus reading channel 0 of a MCP3304 with a potentiometer on it.

2

Set to 5V in

3

Set to 0V in

 

That concludes the case project for the logic analyzer, I would say that it was successful and I feel much better using it without having to worry about shorting the board PCB.

I’ll be back with more projects and updates soon.

Open Workbench Logic Sniffer case – Part 3

Published by:

The glue is not quite set, even after 24 hours and the connectors had shifted so I’ve had to re-glue them 😛

The connectors were also too low set in respect to the OWLS board so I had to raise them up anyway.

 

The next thing I needed to do while I was working on it, was to find a way of keeping the platform that the OWLS board/s are on from sliding forwards when I try to plug in the USB, I decided to to make a small metal spacer that hold onto the platform and push against the in inside of the front panel, I decided to wrap tape around the end so it wouldn’t cut into the wires and come up with a way of it holding onto the platform.

2015-10-21 23.30.20

I basically folded a piece of metal over, used a nibbler to cut a notch out then opened it out.

 

2015-10-21 23.31.05

Here you can see the space in position, I checked it in the case and it seems to be correct.

 

 

2015-10-21 23.50.05

Concerning the connectors, I had to re-glue them as I mentioned above, and I used some cardboard to act as a spacer. I also dolloped some glue onto the spacer to hold it in place. This time to stop them shifting during the gluing, I have used a clamp over the edge of my desk. If this fails, then I’m falling back onto good old hot-glue 😛 I may even just add some for good luck. I don’t expect any heat within the case so I know that isn’t an issue using it.

So it’s time to wait once more for the glue to dry 😛 hopefully the expansion board arrives in the morning so I can get it all in the packed up in it’s case. If not, I will put it all together with it’s 16 channels and upgrade it at a later time. Though I will fit the header and make a cable so the upgrade will be quick.

I will check this again in the morning.