Navigation

Saturday, 11 April 2015

Design of a 4-bit Digital to Analog Circuit

A DAC is a digital to analogue circuit. The microcontroller produces a digital value while the DAC converts it to an analog value. A DAC can be implemented using either a binary-weighted circuit or an R-2R ladder circuit.

For the binary weighted circuit, assuming a 4-bit DAC, there are 16 levels which are from 0-15. Assuming the voltage is between 0 – 5v

Digital Value (N)
b3
b2
b1
b0
Analog Value
0
0
0
0
0
0
1
0
0
0
5.0V
5.0*(1/15)
2
0
0
5.0V
0
5.0*(2/15)
3
0
0
5.0V
5.0V
5.0*(3/15)
4
0
5.0V
0
0
5.0*(4/15)
5
0
5.0V
0
5.0V
5.0*(5/15)
6
0
5.0V
5.0V
0
5.0*(6/15)
7
0
5.0V
5.0V
5.0V
5.0*(7/15)
8
5.0V
0
0
0
5.0*(8/15)
9
5.0V
0
0
5.0V
5.0*(9/15)
10
5.0V
0
5.0V
0
5.0*(10/15)
11
5.0V
0
5.0V
5.0V
5.0*(11/15)
12
5.0V
5.0V
0
0
5.0*(12/15)
13
5.0V
5.0V
0
5.0V
5.0*(13/15)
14
5.0V
5.0V
5.0V
0
5.0*(14/15)
15
5.0V
5.0V
5.0V
5.0V
5.0

The resolution of this DAC which represents the smallest change it can capture is given by the difference between each consecutive elements is 5v/15=0.33V. 

The b0 is the LSB while b3 is the MSB. The resistor values are chosen in the ratio of 1/2/4/8 such that the MSB, b3, is attached to the least value of resistor while the LSB, bo, is attached to the highest value of resistance. Bit 0 is the LSB so it is subjected to a higher resistance, Bit 3 is the MSB so it is subjected to the least resistance. The higher the significance of the bit, the lower is the resistor it is connected to


Doing the analysing of the circuit when N=8 from the table, b3-b0 is given by 1000 where b3 is at 5.0V. This means at the circuit becomes:


The equivalent circuit becomes:



So Vout needs to be obtained. The equivalent resistance of 3KOhms. 6KOhm and 12KOhms in parallel is 12/7 KΩ. Therefore, the circuit can be further reduced to:


From voltage divider rule,

This results in the same analog value for the N= 8 as shown in the table

Taking another condition, say N= 12, the equivalent circuit becomes


The equivalent circuit becomes:


Which can be further reduced to:




This value is also the same as the analogue value in the N=12 row of the table.

Inorder to implement the DAC binary-weighted circuit, the value of resistors required has to be 1/2/4/8/16/32/64 ... which will continue to increase depending on the resolution of the DAC. Therefore a 10-bit DAC will require resistors which are in multiples of 2 up to 1024. Generally, it might be difficult to obtain these resistance values. However, when 2 resistors of the same value are connected in parallel, the resulting resistance is half of the value of each of the resistors. Likewise, connecting 2 same valued resistors in series will produce a resistance that is twice each of the resistor. This can be taken into consideration when the exact value of resistance is not available.

Another way of implementing the DAC is an R-2R ladder network. In this case, just two resistance values are required but the number of resistors needed is increased when compared with the binary weighted circuit



Saturday, 31 January 2015

Wheatstone Brigde

A Wheatstone bridge circuit as shown below is used as a sensor to measure very small voltage in the order of millivolts. It is often used when greater sensitivity is required. The Wheatstone bridge consists of 4 resistors. When all the resistances are equal, no voltage is seen across the bridge. When used as a sensor, resistors R1-R3 are of the same value while the resistance of resistor R4 which is the sensor will vary according according to the change in resistance. R4 can be a photocell whose resistance vary with light intensity, strain guage whose resistance varies with length or a flex sensor that changes resistance based on the degree of bend.

A Wheatstone bridge consist of two voltage divider circuit. As shown in the circuit above, the voltage across R3 is given by:

while the voltage across R4 is given by:

Therefore, the voltage across the Wheatstone bridge is given by:

Since R1 = R2 = R3 = R,

Therefore, if R equals R4, the output voltage is zero; if R is greater than R4, the output voltage is negative; if R is less than R4, the output voltage is positive. The changes in the output voltage is in the order of mV and therefore sensitivity is improved using a Wheatstone bridge configuration. A voltmeter is used to read this voltage. If this output voltage is to be read by a microcontroller, an operational amplifier will be required to amplify the voltage.

Friday, 9 January 2015

Tracking three colours with Processing

This tutorial explains the coding and algorithm to track three colours (red, green and blue) with Processing Language.



import processing.video.*;

Capture video;

void setup() {
  size(640, 480);
  // Uses the default video input, see the reference if this causes an error
  video = new Capture(this, width, height);
  video.start();  
  noStroke();
  smooth();

}

void draw() {
  if (video.available()) {
    video.read();
    image(video, 0, 0, width, height); // Draw the webcam video onto the screen
    
    int pixelRed = 0;   //value of red pixel
    int pixelRed_g = 0;
    int pixelRed_b = 0;
    int redX = 0;           // X-coordinate of the red video pixel
    int redY = 0;           // Y-coordinate of the red video pixel
    int reddest = 0;        // the brightest red pixel in the video
    int reddest_g = 64;
    int reddest_b = 64;
    
    int pixelGreen = 0;  //value of green pixel
    int pixelGreen_r = 0;
    int pixelGreen_b = 0;
    int greenX = 0;          // X-coordinate of the green video pixel
    int greenY = 0;          // Y-coordinate of the green video pixel
    int greenest = 0;        // the brightest green pixel in the video
    int greenest_r = 64;
    int greenest_b = 64;

    int pixelBlue = 0;  //value of blue pixel
    int pixelBlue_r = 0;
    int pixelBlue_g = 0;
    int blueX = 0;          // X-coordinate of the blue video pixel
    int blueY = 0;          // Y-coordinate of the blue video pixel
    int bluest = 0;         // the brightest blue pixel in the video
    int bluest_r = 64;
    int bluest_g = 64;
    
    float brightestValue = 0; // Brightness of the brightest video pixel
    // Search for the brightest pixel: For each row of pixels in the video image and
    // for each pixel in the yth row, compute each pixel's index in the video
    video.loadPixels();
    
    int index = 0;
    for (int y = 0; y < video.height; y++) {
      for (int x = 0; x < video.width; x++) {
        // Get the color stored in the pixel
        color pixelValue = video.pixels[index];
        
        // Extract the red, green, and blue components of the current pixel's color
        int currR = (pixelValue >> 16) & 0xFF;
        int currG = (pixelValue >> 8) & 0xFF;
        int currB = pixelValue & 0xFF;
      
        // If that value is red, find the brightest pixel and store its (x,y) location 
        
        if ( (currR > 128) && (currG < 64) && (currB < 64) ) {
          pixelRed = currR; pixelRed_g = currG; pixelRed_b = currB;
          if ((pixelRed > reddest) && (pixelRed_g < reddest_g) && (pixelRed_b < reddest_b)) {
            reddest = pixelRed; reddest_g = pixelRed_g; reddest_b = pixelRed_b;
            redY = y;
            redX = x;
          }
        }
        
        
        // If that value is green, find the brightest pixel and store its (x,y) location
        if ( (currR < 64) && (currG > 64) && (currB < 64) ) {
          pixelGreen = currG; pixelGreen_r = currR; pixelGreen_b = currB;
          if ((pixelGreen > greenest) && (pixelGreen_r < greenest_r) && (pixelGreen_b < greenest_b)) {
            greenest = pixelGreen; greenest_r = pixelGreen_r; greenest_b = pixelGreen_b;
            greenY = y;
            greenX = x;
          }
        }
        
        // If that value is blue, find the brightest pixel and store its (x,y) location
        
        if ( (currR < 64) && (currG < 64) && (currB > 128) ) {
          pixelBlue = currB; pixelBlue_r = currR; pixelBlue_g = currG;
          if ((pixelBlue > bluest) && (pixelBlue_r < bluest_r) && (pixelBlue_g < bluest_g)) {
            bluest = pixelBlue; bluest_r = pixelBlue_r; bluest_g = pixelBlue_g;
            blueY = y;
            blueX = x;
          }
        }
        
        index++;
      }
    }
    
    // Draw a red circle at the red pixel
    fill(255, 0, 0, 255);
    ellipse(redX, redY, 20, 20);
    
    // Draw a green circle at the green pixel
    fill(0, 255, 0, 255);
    ellipse(greenX, greenY, 20, 20);
    
    // Draw a blue circle at the blue pixel
    fill(0, 0, 255, 255);
    ellipse(blueX, blueY, 20, 20);
    
  }
}

Connecting a switch to a microcontroller: Pull-Up and Pull-Down Resistors

A switch can be connected to a microcontroller using either a pull-up or pull-down resistor. The pull-up and pull-down resistors ensure that the wire is at a defined logic level even if no active devices are connected to it.

Pull-Up Resistor



Pull-up resistor pulls the voltage of the wire it is connected to towards the voltage source level when all the other components on the line are inactive. When all other components on the line are inactive, they are high impedance and act like they are disconnected. The pull-up resistor brings the wire up to the HIGH logic level. When another component goes active, it will override the HIGH logic level set by the pull-up resistor. The microcontroller is HIGH when the switch is not connected and LOW otherwise.

Pull-Down Resistor



A pull-down resistor works in the same way but it is connected to GND. It holds the logic signal near zero volts when no other active device is connected. The microcontroller is LOW when the switch is not connected but HIGH otherwise. It is preferable to use a pull-down resistor.

Tuesday, 23 December 2014

How to Connect LED (Current Source and Sink)

A Light Emitting Diode (LED) can be connected in either way as shown the the following diagrams:


When connecting an LED to a microcontroller, a current source or current sink configuration can be followed.

For Current Source configuration, the LED output is sourcing current so it flowing out of the microcontroller output. In this case, the LED is connected between the GND and the microcontroller output pin. This means that the LED will be switched ON when the microcontroller output is HIGH and switched OFF when the microcontroller output is LOW. This is as shown below, D13 is represented by a pin on the microcontroller.

For a Current Sink Configuration shown below, the LED output is sinking current since it is flowing into the microcontroller output. Tn this case, the LED is connected between the positive supply and the microcontroller output. This means that the LED will be switched ON when the microcontroller output is LOW, and will be switched OFF when the microcontroller output is HIGH.
To determine the value of the current limiting resistor to use, the formula bellow is used:
Where Vcc is the supply voltage; Vf is the LED forward voltage and I is the LED forward current. Vf and I are given in the datasheet of the LED. Therefore, if a supply voltage of 5V is to be used and Vf=1.5V; I = 10mA, the current limiting resistor to be connected will be given by



Monday, 22 December 2014

DC Barrel Power Jack Socket Pinout

This is a common barrel-type power jack for DC wall supplies. Its pinout is as shown in the figure below.

Saturday, 20 December 2014

How to Connect LCD to the Arduino


A Liquid Crystal display is connected as follows. D12, D11, D5 - D2 pins as shown in the figure above corresponds to pins 12, 11, 5 - 4 pins on the Arduino. For the VEE pin, a 10KOhm potentiometer can be used instead. For a 16-pin LCD, the A pin is connected to 5v while the K pin is connected to GND. It is optional to connect the A and K pins as they are used for the backlight of the LCD.

Sunday, 30 November 2014

TBPDANS001PGUCV Pressure Sensor

The TBPDANS Pressure Sensor is a range of pressure sensor that comes in different pressure range, i.e. from 0 - 1psi; 0 - 5psi; 0 - 100psi, etc. The sensor contains a Wheatstone bridge  and the voltage between the Vout- and Vout+ pins has to measured.

If an Arduino microcontroller is to be used with this sensor, two analog input pins has to be used to measure Vout_ and Vout+ and the difference between these readings will give the voltage as a function of the pressure. But this result of subtracting Vout-  from Vout+ is in the order of 0.1millivolts and therefore the reading will not be evident when using the Arduino because the Arduino uses 10-bit ADC and so the sensitivity for 5v reference is:
This clearly is insufficient as we need a sensitivity less than 0.1mV. If the reference voltage is changed to 3.3v by connecting the AREF pin to 3.3v and writing the code below in the void setup() function:

void setup () {
analogRefence(EXTERNAL); // use AREF for reference voltage
}
This is also inadequate for our use
Also using the 1.1v internal reference of the Arduino by adding the code:
void setup () {
analogRefence(INTERNAL);    // use 1.1v internal reference voltage
}
This resolution is quite good but it should be noted that the using a full scale voltage of 1.1v will result in the maximum voltage that can be measured to be 1.1v. This implies that careful selection as to be made to the supply voltage given to the pressure sensor. The typical supply voltage according to the datasheet is 5v; minimum is 1.5v; maximum is 12v. If a voltage of 5v is applied to the Vcc pin of the pressure sensor, the voltage on the Vout- pin will be the supply voltage divided by 2, i.e. 2.5v while the voltage on the Vout+ pin will be 2.5v plus millivolt changes as the pressure changes.
Therefore using a 1.1v full scale reference will be inadequate, because although we have a higher sensitivity, we cannot measure voltages above 2.5v. 

The solution might be to lower the supply voltage to the pressure sensor. A better solution is to use an op-amp to amplify the voltage to the range the Arduino can measure. INA125 op amp can be used for this. Another better solution is to use a higher ADC bit IC such as a 12-bit ADC or 16-bit ADC or 24-bit ADC.

An example code to read the voltage from the TBPDANS005PGUCV sensor is:

int sensorValue1 = 0;
int sensorValue2 = 0;
float Voutminus;
float Voutplus;
float Vout;
void setup() {
     analogReference(EXTERNAL); // connect AREF pin to the reference voltage being used
                                      // analogReference(INTERNAL) can be used for 1.1v reference on Arduino Uno
     Serial.begin(9600);  
}
void loop() {
 
    sensorValue1 = analogRead(A0);
    sensorValue2 = analogRead(A1);
   
    Voutminus  = (analogRead(A0) * 5000.00) / 1023;   // Voltage in mV
    Voutplus = (analogRead(A1) * 5000.00) / 1023;         // Voltage in mV
    Vout = Voutplus – Voutminus;
    Serial.println(sensorValue1);
    Serial.println(sensorValue2);
    Serial.println(“Vout: ”, Vout, “mV”);
    Serial.println();
   
    delay(2000);          
}


Saturday, 15 November 2014

Programming the ASDXACX100PAAA05 pressure sensor


The ASDXACX100PAAA05 pressure sensor is an absolute pressure sensor, that is it measures atmospheric pressure plus any other pressure in the system.

  • Maximum pressure, Pmax is 100psi. Minimum pressure, Pmin is 0psi
  • Power supply is +5V
  • Supply current is 2.5mA
  • It uses 10% - 90% calibration
  • It uses 12-bit analogue output

Pinout: It has 8 pins, three are used, the remaining are not connected

Arduino uses 10-bit ADC (0 - 1023). Therefore the output voltage from the Arduino is in the range og 0 - 1023. Hence, must be converted to its voltage form. This is achieved by mapping 0 1 1023 to 0 - 5v as shown by the equation below.
Reading the voltage from Arduino: The transfer function limits define the output of the sensor at a given pressure input. By specifying the output signal at the maximum (Pmax) and minimum (Pmin) limit of the pressure range, the complete transfer curve for the sensor is defined.
It uses 10% - 90% of the supply voltage and maps it to Pmin and Pmax respectively. That is:

  • At 10% of Vsupply (0.5v), Pmin equals 0psi
  • At 90% of Vsupply (4.5v), Pmax equals 100psi

Pmax = maximum limit of pressure range = 100psi
Pmin= minimum limit of pressure range = 0psi

The equation of the transfer function is:


Therefore, at atmospheric pressure (14.696psi), output voltage should equal:
Therefore, pressure applied equals:

The Arduino Code:


/*

 Reads an analog input pin, converts it to voltage and calculates the corresponding output pressure
 Also prints the results to the serial monitor.

 The circuit:
 * ASDX pressure sensor pin 2 connected to analog pin 0.
   pin 1 connected to Vcc (+5v for ASDXACX100PAAA05)
   pin 3 connected to GND
   the other pins are not connected
 * 

 created 15 July. 2014
 by Toria Olawumi

 */

const int ADCFULLSCALE = 1023;               // ADC full scale of arduino is 10-bit (0-1023)
const float reference_voltage_mv = 5000.0;   // Vcc is 5000mv (5V) for ASDXACX100PAAA05
const int Pmax = 100;                       // 100psi for ASDXACX100PAAA05
const int Pmin = 0;                         // 0 psi FOR ASDXACX100PAAA05

const int analogInPin = A0;     // Analog input pin that the asdx pressure sensor is attached to

int sensorValue = 0;           // value read from the pressure sensor

float voltage_mv = 0.0;         // pressure sensor voltage in mV
float voltage_v = 0.0;         // pressure sensor voltage in volts
float output_pressure = 0.0;   // output pressure in psi
float vacuum_pressure = 0.0;   // (substract atmospheric pressure from output_preesure) // vacuum pressure in psi

void setup() {
    Serial.begin(9600); 
}
void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);                              // digital value of pressure sensor voltage
  voltage_mv =  (sensorValue * reference_voltage_mv) / ADCFULLSCALE;   // pressure sensor voltage in mV
  voltage_v = voltage_mv / 1000;
  Serial.println(voltage_v);
  output_pressure = ( ( (voltage_v - (0.10 * (reference_voltage_mv/1000) )) * (Pmax - Pmin) ) / (0.8 * (reference_voltage_mv/1000) ) ) + Pmin;
  vacuum_pressure = output_pressure - 14.6; // subtract atmospheric pressure
}