It was in my schooling days over 2 decades ago when I first came across PWM (Pulse-Width Modulation). I am fascinated by how efficient it can be utilize in a myriad of power electronics application. The working principle is easy to understand but implementing isn't ... Well, at least to me at that point of time when anything that requires micro-processor is considered alien technology or witch craft.... After all it was the age of 8086 XT & I was only a poor teenage student without internet & any common interest friends let alone finding any mentor to guide me in the pursuit...
Every now & than over the years, I encounter numerous literature on microprocessor use in PWM thingy... Not that I'm a genius, but after over a decade of leisure reading, it has came to the point that I just had to have a go at it.
Personally, I consider Arduino is a blessing, it has everything I need to get it done. Without it, I would never had bothered tinkering with micro-controller.
The plan is to build an experimental DC motor controller with
1) Potential meter (POT) as Direction & Speed control dialing nob.
2) Arduino as the micro-controller.
3) ~16kHz PWM frequency to keep the motor running quiet
Here is the code I wrote. Short, but that is all that is required.
#include <avr/interrupt.h>
//Analog Pins Allocation
int POT_pin = 0; //Speed & direction control POT connect to A0
//Digital Pins Allocation
int IN1 = 7; //Controller IN1 pin connect to D7 Pin
int IN2 = 8; //Controller IN2 pin to connect D8 Pin
int INH = 9; //INH1 & INH2 are common & comnect to PWM D9 Pin
// Variables
int Motor_speed = 0; //Motor speed to achieve balancing
void setup() {
TCCR1A = B11110010;
TCCR1B = B00011001;
TCCR1B = 25;// 00011001
ICR1 = 1023 ; // 10 bit resolution
OCR1A = 511; // vary this value between 0 and 1024 for 10-bit precision
OCR1B = 511; // vary this value between 0 and 1024 for 10-bit precision
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (INH, OUTPUT); //PWM Analog
}
void loop()
{
Motor_speed = map(analogRead(POT_pin),0,1024,-1023,1023);
if (Motor_speed>0)
{
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
}
else
{
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
}
analogWrite(INH,(1023-abs(Motor_speed)));
//the "1023-" is there to correct the actual PWM percentage with respect to the POT
}
The required power electronics will come in Part 2...
Sunday, August 26, 2012
Saturday, July 14, 2012
Tinkering Accelerometer + Gyro AKA IMU (Part 3)
Now that we know how to read the sensors, we need to make sense of it. Lets have a good look at the sensor datasheet.
ADXL335 3-axis Accelerometer
Accelerometer, measures resultant acceleration acting on the sensor.
This ADXL335 outputs an analogue voltage based on acceleration. Its sensitivity of the ADXL335 is 300mV/g, which means that the output will change by .30v per 9.8m/s2 .
The ADXL335 has a ratiometric output, meaning 0g is always around half of the supply voltage Vcc, The datasheet stated that the zero Voltage is typically at 1.5V.
Hence,
Accel = Vaccel - 1.5V
BUT I prefer to get the actual count reading when the accelerometer is resting on horizontal position
and Sensitivity is typically 0.3V/g, the Arduino ADC gives a 10-bit value based on a 3.3v reference, the gain on the raw ADC value can be calculated by:
Hence,
(1g/0.3V) X (3.3V/1024) =0.01627 g/LSB
Hence,
Position of the accelerometer = Accel *0.011
IDG500 2-axis Gyro
This gyroscope measures angular rate and return a analogue voltage signal proportional to the rate of rotation. The at the 4.5x, IDG500 has a sensitivity of 9.1mV/°/s, i.e. the output changes 9.1.0mV for every °/s of rotation. Since the Arduino ADC gives a 10-bit value based on a 5v reference, the gain on the raw ADC value can be calculated by:
(1°/s/0.0091V) X (3.3/1024) = 0.354 °/s/LSD
deduct the factory set 1.35V from raw analogue input & multiplying result with 0.354°/s/LSD will return the angular velocity in degrees-per-second.
Gyro rate =(Gyro_reading - 1.35V)*0.354 deg/sec
Since we are doing discrete maths with our controller, we multiply the known interval between gyro reading which is the loop time; we get the change in angular position in degree
Gyro Angular change = Gyro rate * Loop time
Now we have enough data to measure angular position with the gyro with the following line.
Gyro angle= Gyro angle + Gyro Angular change.
What we had just done is to rationalised both the accelerometer & gyro output to angular position with the same unit of measurement.
It is now convenient to write code to compare the sensors on the same page.
ADXL335 3-axis Accelerometer
Accelerometer, measures resultant acceleration acting on the sensor.
This ADXL335 outputs an analogue voltage based on acceleration. Its sensitivity of the ADXL335 is 300mV/g, which means that the output will change by .30v per 9.8m/s2 .
The ADXL335 has a ratiometric output, meaning 0g is always around half of the supply voltage Vcc, The datasheet stated that the zero Voltage is typically at 1.5V.
Hence,
Accel = Vaccel - 1.5V
BUT I prefer to get the actual count reading when the accelerometer is resting on horizontal position
and Sensitivity is typically 0.3V/g, the Arduino ADC gives a 10-bit value based on a 3.3v reference, the gain on the raw ADC value can be calculated by:
Hence,
(1g/0.3V) X (3.3V/1024) =0.01627 g/LSB
Hence,
Position of the accelerometer = Accel *0.011
IDG500 2-axis Gyro
This gyroscope measures angular rate and return a analogue voltage signal proportional to the rate of rotation. The at the 4.5x, IDG500 has a sensitivity of 9.1mV/°/s, i.e. the output changes 9.1.0mV for every °/s of rotation. Since the Arduino ADC gives a 10-bit value based on a 5v reference, the gain on the raw ADC value can be calculated by:
(1°/s/0.0091V) X (3.3/1024) = 0.354 °/s/LSD
deduct the factory set 1.35V from raw analogue input & multiplying result with 0.354°/s/LSD will return the angular velocity in degrees-per-second.
Gyro rate =(Gyro_reading - 1.35V)*0.354 deg/sec
Since we are doing discrete maths with our controller, we multiply the known interval between gyro reading which is the loop time; we get the change in angular position in degree
Gyro Angular change = Gyro rate * Loop time
Now we have enough data to measure angular position with the gyro with the following line.
Gyro angle= Gyro angle + Gyro Angular change.
What we had just done is to rationalised both the accelerometer & gyro output to angular position with the same unit of measurement.
It is now convenient to write code to compare the sensors on the same page.
Labels:
Accelerometer,
Arduino,
electronics,
Gyroscope,
IMU
Tuesday, May 1, 2012
Tinkering Accelerometer + Gyroscope AKA IMU (Part 2)
The IMU is a combo board consisting of 2 sensors.
What good is a sensor if we can not read it.
Here I jury jig a bench top test for reading the sensors.
Hardware involved:-
Arduino Duemilanove
5DOF IMU
some hook-up leads
- 3V3 to IMU Vss & ARef pin
-Gnd to Gnd
- accel X axis to Analog input 0
- accel Y axis to Analog input 2
- gyro X axis(4x output) to Analog input 1
- gyro Y axis(4x output) to Analog input 3
- USB cable
We still need to write some codes to get the job done.
Following is a simple code which I came up with
// Reading 5DOF IMU
//Analog Pins
int Xaccel_pin = 0; //connect accel X axis to Analog input 0
int Yaccel_pin = 2; //connect accel X axis to Analog input 2
int Xgyro_pin = 1; //connect gyro X axis(4x output) to Analog input 1
int Ygyro_pin = 3; //connect gyro Y axis(4x output) to Analog input 3
//Digital Pins
int Xaccel_reading; //X axis Accelerometer reading
int Yaccel_reading; //y axis Accelerometer reading
int Xgyro_reading; //X axis Gyro reading
int Ygyro_reading; //Y axis Gyro reading
float loop_time = 0.05;
int last_loop = 0;
void setup(){
Serial.begin(9600); // start Serial monitor to print values
pinMode(Xaccel_pin,INPUT);
pinMode(Xgyro_pin,INPUT);
pinMode(Yaccel_pin,INPUT);
pinMode(Ygyro_pin,INPUT);
pinMode(13,OUTPUT);
}
void loop() {
Xaccel_reading=analogRead(Xaccel_pin);
Xgyro_reading=analogRead(Xgyro_pin);
Yaccel_reading=analogRead(Yaccel_pin);
Ygyro_reading=analogRead(Ygyro_pin);
while((millis()-last_loop)
{
delay(1);
}
last_loop=millis();
Serial.print("X-Accel: ");
Serial.print(Xaccel_reading);
Serial.print(" ");
Serial.print("X-Gyro: ");
Serial.print(Xgyro_reading);
Serial.print(" ");
Serial.print("YAccel: ");
Serial.print(Yaccel_reading);
Serial.print(" ");
Serial.print("Y-Gyro: ");
Serial.print(Ygyro_reading);
Serial.print(" ");
}
What good is a sensor if we can not read it.
Here I jury jig a bench top test for reading the sensors.
Hardware involved:-
Arduino Duemilanove
5DOF IMU
some hook-up leads
- 3V3 to IMU Vss & ARef pin
-Gnd to Gnd
- accel X axis to Analog input 0
- accel Y axis to Analog input 2
- gyro X axis(4x output) to Analog input 1
- gyro Y axis(4x output) to Analog input 3
- USB cable
We still need to write some codes to get the job done.
Following is a simple code which I came up with
// Reading 5DOF IMU
//Analog Pins
int Xaccel_pin = 0; //connect accel X axis to Analog input 0
int Yaccel_pin = 2; //connect accel X axis to Analog input 2
int Xgyro_pin = 1; //connect gyro X axis(4x output) to Analog input 1
int Ygyro_pin = 3; //connect gyro Y axis(4x output) to Analog input 3
//Digital Pins
int Xaccel_reading; //X axis Accelerometer reading
int Yaccel_reading; //y axis Accelerometer reading
int Xgyro_reading; //X axis Gyro reading
int Ygyro_reading; //Y axis Gyro reading
float loop_time = 0.05;
int last_loop = 0;
void setup(){
Serial.begin(9600); // start Serial monitor to print values
pinMode(Xaccel_pin,INPUT);
pinMode(Xgyro_pin,INPUT);
pinMode(Yaccel_pin,INPUT);
pinMode(Ygyro_pin,INPUT);
pinMode(13,OUTPUT);
}
void loop() {
Xaccel_reading=analogRead(Xaccel_pin);
Xgyro_reading=analogRead(Xgyro_pin);
Yaccel_reading=analogRead(Yaccel_pin);
Ygyro_reading=analogRead(Ygyro_pin);
while((millis()-last_loop)
{
delay(1);
}
last_loop=millis();
Serial.print("X-Accel: ");
Serial.print(Xaccel_reading);
Serial.print(" ");
Serial.print("X-Gyro: ");
Serial.print(Xgyro_reading);
Serial.print(" ");
Serial.print("YAccel: ");
Serial.print(Yaccel_reading);
Serial.print(" ");
Serial.print("Y-Gyro: ");
Serial.print(Ygyro_reading);
Serial.print(" ");
}
Once loaded, you can see the IMU reading via the "Serial Monitor" or <>
Now that I have IMU readings, the next gargantuan task is to figure out what can I do with them...
Maybe in Part 3 I'll have an answer....
Labels:
Accelerometer,
Arduino,
DIY Robotic,
Gyroscope,
IMU,
mcu,
Sensor
Saturday, April 21, 2012
Tinkering Accelerometer + Gyroscope AKA IMU (Part 1)
Its been some time since I fiddle with anything interesting...
The amplifier chassis is fun but just couldn't drag myself to build it as it doesn't arouse any sense of achievement since it never do anything at all...

Dug out this dust covered 5DOF IMU from my hoarder's corner...
I bought this for a song while roaming mindlessly in the deep internet space sometime ago...
Doing something with this will surely beats any amplifier projects.
Let me introduce you to this little gem.
It is an analogue output 5DOF(Degree of Freedom) IMU (Inertia Moment Unit) board consisting of 3 axis accelerometer ADXL335 chip by Analog Devices and 2 axis gyroscope chip IDG500 by InvenSense.
This will save me from soldering 2 multi-legged SMT chip which are about the size of my nostril hair.
SPECIFICATIONS
Word budget is up for this article. In the part 2 of this series of article, I'll dive into reading the IMU which will involve some maths, some coding & some simple point to point wiring.
The amplifier chassis is fun but just couldn't drag myself to build it as it doesn't arouse any sense of achievement since it never do anything at all...

Dug out this dust covered 5DOF IMU from my hoarder's corner...
I bought this for a song while roaming mindlessly in the deep internet space sometime ago...
Doing something with this will surely beats any amplifier projects.
Let me introduce you to this little gem.It is an analogue output 5DOF(Degree of Freedom) IMU (Inertia Moment Unit) board consisting of 3 axis accelerometer ADXL335 chip by Analog Devices and 2 axis gyroscope chip IDG500 by InvenSense.
This will save me from soldering 2 multi-legged SMT chip which are about the size of my nostril hair.
SPECIFICATIONS
Accelerometer
AnalogDevices
ADXL335
Axis
|
X, Y, Z
|
Measuring Range
|
±3.6g
|
Non-Linearity
|
±0.3%
|
Vcc
|
3.3V
|
Sensitivity at Xout, Yout, Zout
|
270~330mV/g,
typically 300mV/g
|
Zero g Bias Level (Ratiometric)
0g Voltage at Xout, Yout
0g Voltage at Zout
|
1.35~1.65V,
typically 1.5V
1.2~1.8V,
typically 1.8V
|
Frequency Response
Bandwidth Xout, Yout
Bandwidth Zout
|
1600Hz
550Hz
|
Gyrometer
InvenSense
IDG500
Axis
|
X, Y
|
|
Full-Scale Range
Sensitivity
|
X-OUT & Y-OUT
X4.5Out & Y4.5Out
X-OUT & Y-OUT
X4.5Out & Y4.5Out
|
±500°/s
±110°/s
2.0mV/°/s
9.1mV/°/s
|
Frequency Response
|
140
Hz
|
|
Zero-Rate Output
Static (Bias)
|
Factory set
1.35V
|
|
Vcc
|
3.3V
|
IMU SHIELD
Even though it is a breakout board, This thing is still tiny my my standard!
To save my sanity & eyesight, I drawn up a PCB as shield for Arduino.
![]() |
| IMU Arduino Shield |
By fiddling with the jumper pin, I can choose which ever accelerometer axis Xout,Yout or Zout to A0 pin & Gyro's X-OUT, Y-OUT, Z-OUT, X4.5Out or Y4.5Out to A1 pin just
Others stuff the PCB design to do,
1) tied up the Vcc to the Arduino ARef pin.
2) add pads & holes so that there is an option to solder or using pin plug to get to the Arduino pinouts.
Word budget is up for this article. In the part 2 of this series of article, I'll dive into reading the IMU which will involve some maths, some coding & some simple point to point wiring.
Friday, October 7, 2011
Aikido Pre-Amp Project - part 9
My brother came with a home-made chassis; Something my brother designed some years ago. 18"x12"x 4" high.
This is the chassis after a quick clean up.
This will be a great time saver since I've already spent nearly 60hrs on the project & any quick solution put things back into prospective.
This is the new amendment to the layout.
Ample real estate available.
As I'll not use a separate base plate for mounting the irons, it will be difficult to mount the previously selected irons. So I've change the 2 transformers to vertical mount type EI laminate tranny.
Since he don't require source selection, so the selector switch is obmitted.
Now, I need to find suitable IRC sockets that will fiit the opening already on the chassis.
I'll fill in the common mode filter & other switches & socket when I can find more time for it.
This is the chassis after a quick clean up.
This will be a great time saver since I've already spent nearly 60hrs on the project & any quick solution put things back into prospective.
This is the new amendment to the layout.
Ample real estate available.
As I'll not use a separate base plate for mounting the irons, it will be difficult to mount the previously selected irons. So I've change the 2 transformers to vertical mount type EI laminate tranny.
Since he don't require source selection, so the selector switch is obmitted.
Now, I need to find suitable IRC sockets that will fiit the opening already on the chassis.
I'll fill in the common mode filter & other switches & socket when I can find more time for it.
Sunday, October 2, 2011
Aikido Pre-amp Project - Part 8
It is easy to get carried away & fall pray to unnessary desires & unrealistic wants.
Time to put on my contractor hat & give the whole PSU a final round of scrutiny.
Keep-It-Simple-Stupid....
Virtual capacitor
I have never suffer premature valve failure other than applying brute force with a blunt object on them... I've yet to see any valve died of voltage stress... Seriously, what can 30ma current surge do??? or even 300ma??? Tubes are built to take brutality like fish in water!!! So it will reduce the valve life from 200,000 hours to 180,000hour... so what!?
Aikido were born with PS ripples cancellation. Let them do what they do best!
This is a class A1 amp, the load behaviour is almost a constant current and the signal source will most likely be solely fed from a CD player or a DAC with 2Vrms signal, it will never come close to clipping! Moreover, since it is not a power buffer stage with transformer coupling, high power supply Zo is not a real issue.
Why bother with the extra works when one can get away with it???
Another visit to PSU2 & came up with these component numbers, the damping is sightly over 1 which is where my preference lies.
Final check,
A costumed RFI/EMI common-mode filter,
All important last line of defence, 0.1A fuse,
The indispensable power rocker switch,
Obviously essential IEC power socket,
A spikes treated rectifier bridge,
A snubber treated choke,
A CLC network which gives a well damped & quiet B+,
A floated AC filament supply with twisted solid core leads.
This should put everything back in prospective & an end to the PSU design...
<<<<>>>>
Another look at the chassis...
Saturday, October 1, 2011
Aikido Pre-amp Project - Part 7
Correction....
My bad..... Made a blunder with the capacitor multiplier schematic in the last post...
This is the correct schematic.
I forgot about the potential divider for biasing the MOSFET. My bad.
In doing so, we will reduce the B+ by 5% & also provide a short term regulation of +/-10%. Hence, smooth out sudden mains voltage fluctuation within to 5%.
In the long term sense, the B+ will track the mains voltage fluctuation.
Under New Management
In this new arrangement, the gyrator is after the CLC network filter, just like how everyone else arrange their voltage regulator.
Since we happened to have a gyrator in the circuit. Might as well let them do what they do best i.e. reduce Zo to single digit & excellent ripple reduction.
Now I can reshuffle the component values of the CLC to achieve the damping factor which I am looking for, highest B+ possible & lessen capacitance further.
Added a 220R 5W resistor in series to the choke, this was not an option earlier as it will add on the PSU Zo, with this, I can reduce 120uf to 47uf.
I could had use 10uf at the last cap, but the gyrator only mimic a huge capacitor without actually storing any real energy, so using a 47uf as reservoir seems reasonable.
Also, 3 more snubber capacitors for the rectifier, now, there is a snubber cap for every diode in the bridge rectifier. This will work better yet still not too much work...
We loss about 15V on the B+ with the gyrator & CLC amendments, but I consider that a bargain with the added slow-ramp, cleaner, stable B+, better damping pattern & reduced Zo significantly.
My bad..... Made a blunder with the capacitor multiplier schematic in the last post...
This is the correct schematic.
I forgot about the potential divider for biasing the MOSFET. My bad.
In doing so, we will reduce the B+ by 5% & also provide a short term regulation of +/-10%. Hence, smooth out sudden mains voltage fluctuation within to 5%.
In the long term sense, the B+ will track the mains voltage fluctuation.
Under New Management

Since we happened to have a gyrator in the circuit. Might as well let them do what they do best i.e. reduce Zo to single digit & excellent ripple reduction.
Now I can reshuffle the component values of the CLC to achieve the damping factor which I am looking for, highest B+ possible & lessen capacitance further.
Added a 220R 5W resistor in series to the choke, this was not an option earlier as it will add on the PSU Zo, with this, I can reduce 120uf to 47uf.
I could had use 10uf at the last cap, but the gyrator only mimic a huge capacitor without actually storing any real energy, so using a 47uf as reservoir seems reasonable.
Also, 3 more snubber capacitors for the rectifier, now, there is a snubber cap for every diode in the bridge rectifier. This will work better yet still not too much work...
We loss about 15V on the B+ with the gyrator & CLC amendments, but I consider that a bargain with the added slow-ramp, cleaner, stable B+, better damping pattern & reduced Zo significantly.
..........PREVIEW Part 8..........
Closure
Subscribe to:
Posts (Atom)




