Some time ago we noticed that Cornel University ECE4760 project list started to build up. It seems that the project list is finished with 30 great projects built around AVR microcontrollers. Students as always prove to be creative and inspiring. Like each year they came up with new ideas and implementations. We like that they use free tools to build them. The compiler they use is WinAVR/GCC compiler. So everyone can replicate one or another idea if needed.

It is hard to go through whole project list as it would tike time and we still wouldn’t be able to tell the thing. Some of them really are worth attention like EEG Pong, where device reads brain waves and this controls computer cursor. There is even a simple demo software where you can play pong only by moving bar with thought. Another interesting concept is a TicTocTrac wristwatch which not only tells the time but also keeps track of your activity and helps to improve time perception or at least to slow time sense. One student team have built a neural network perceptron that can recognize handwriting. If you attended a Machine Learning online class you should know what difficulties they faced.

Be sure to check all projects as each of them is great and inspiring. If your brain dried out of ideas this may be a refresher to start new interesting projects. And of course big thank you to ECE4760 team for making those projects public.

[via: http://www.scienceprog.com/]

 

Seven segment LED displays are a very popular mean of displaying numerical information and finds application in front panel display boards of microwave ovens, washers and dryers, digital clocks, frequency counters, and many other gadgets. Compared to the LCD displays, the seven segment LED displays are brighter and provide a far viewing distance and a wide viewing angle. However, the downside is they are resource-hungry. It requires at least 12 I/O pins of a microcontroller to drive a standard 4-digit seven segment LED module. Consequently, their use with low pin-count microcontrollers (such as PIC12F series) is not practically feasible. Here’s a solution for that. The following 4-digit seven segment LED module features a serial interface that requires only 3 I/O pins of a microcontroller and provides full control of all digits and decimal points .

Four digit serial 7-segment LED display

Description

This display module is based on the MAX7219 display driver chip from MAXIM. It provides a serial interface to drive 7-segment LED displays (common-cathode type) up to 8 digits. Included on-chip are a BCD decoder, multiplex scan circuitry, segment and digit drivers, and an 8×8 static RAM to store the digit values. The segment current for all LEDs is set through only one external resistor. However, the device also provides a digital control of the display brightness (16 steps from minimum to maximum) through an internal pulse-width modulator.

Finished

The display module is powered with +5V supply applied to its Vcc pin. Data can be transferred to the display module through SPI interface. Connections are available on the board to access the required signal lines (MOSI, CLK, and CS) for communication between the SPI Master (microcontroller) and the MAX7219 chip. Data is sent in 16-bit packets (two bytes) which is shifted into the internal 16-bit shift register with each rising edge of CLK. The 16-bit packet is labeled as D0-D15, where D0-D7 contain the data, D8-D11 contain the register address, and D12-D15 are don’t care bits. D15 is the most significant bit (MSB) and is the first bit to receive. Although the MAX7219 chip can drive up to 8 digits, only 4 digits are implemented here. They are DIG0 through DIG3, arranged in sequence from the right to the left. The 4-bit addresses (D8-D11) of their corresponding digit registers are 0×01, 0×02, 0×03, and 0×04, respectively. The digit registers are realized with an on-chip 8×8 SRAM, and are addressed directly so that individual digits can be updated at any time. The following table lists the complete addressable digit and control registers of the MAX7219 device.

Register address map of MAX7219

Control Registers

The MAX7219 contains 5 control registers: decode mode, display intensity, scan limit (number of scanned digits), shutdown, and display test (all LEDs on).

Shutdown

On initial power-up, all control registers are reset, and the MAX7219/MAX7221 enters into Shutdown mode. In the shutdown mode, the display is blanked. The D0 bit of the Shutdown register (address 0x0C) must be set to bring the display to normal operation. The same bit can be cleared anytime during operation to enter back into the Shutdown mode. During Shutdown, the contents of the data and control registers are unaltered. Shutdown can be used to save power or as an alarm to flash the display by successively entering and leaving the Shutdown mode.

The MAX7219 device can be put in the Shutdown mode by sending two bytes 0x0C (address) and 0×00 (data) in sequence. Similarly, 0x0C followed by 0×01 brings it back to normal operation.

Decode-Mode

The decode-mode register (address 0×09) sets BCD code B (0-9, E, H, L, P, and -) or no-decode operation for each digit. Each bit in the register corresponds to one digit. A logic high selects code B decoding while logic low bypasses the decoder. When the code B decode mode is used, the decoder looks only at the lower nibble of the data in the digit registers (D3–D0), disregarding bits D4–D6. The D7 bit is independent of the decoder and turns the decimal point on if it is set (D7=1). For example, sending bytes 0×02 and 0×05 in sequence sets the DIG1 (second digit from the right) to display decimal 5. Similarly, 0×01 followed by 0×89 displays decimal 9 at DIG0 with its decimal point set. The following table provides the complete list of the code B font.

Code B font

When no-decode is selected, data bits D7–D0 correspond to the segment lines (A-G and DP) of the seven segment display.

No-Decode Mode Data Bits and Corresponding Segment Lines

Intensity control

The MAX7219 allows display brightness to be controlled through software by an internal pulse-width modulator (PWM). The PWM output is controlled by the lower nibble (D3-D0) of the intensity register (address 0x0A) and allows 16 brightness levels. The zero nibble value sets the display intensity to minimum, whereas all nibble bits set to 1 selects the maximum intensity level for the display.

Scan-Limit

The scan-limit register (address 0x0B) sets how many digits are to be displayed from 1 to 8. For a 4-digit display, the scan-limit register value should be set to 0×03.

Display-Test

The display-test register has address 0x0F and allows to turn all LEDs on by overriding, but not altering, the values of the control and digit registers. In order to enable the display-test mode, the D0 bit of the display-test register must be set. The same bit must be cleared to get back to the normal operation.

Interfacing with a microcontroller

The serial 7-segment LED display module can be interfaced with any microcontroller that has 3 I/O pins available. If the microcontroller features a built-in hardware SPI, then the display module can be interfaced as a SPI slave device. In that case the SPI signal lines SDO (serial data out), SCLK (serial clock), and SS (slave select) from the microcontroller can be directly connected to the MOSI, CLK, and CS pins labeled on the display module. CS is active low signal.

In case the host microcontroller doesn’t have a hardware SPI module, the interface can be implemented in software. The SPI communication starts with holding CS pin LOW and then sending 16 bits of data serially (MSB first) over the MOSI pin at the rising edge of CLK signal, and finally pulling the CS pin back to HIGH. The following example illustrates how to write a software SPI routine to drive the display module with three general purpose I/O pins of the PIC12F683 microcontroller. The program is written in mikroC Pro for PIC compiler but can be easily modified for other high-level compilers. The GP0, GP1, and GP2 pins of the PIC12F683 drives the CS, MOSI, and CLK pins, respectively, of the 7-segment display module to create a 4-digit up-counter. The counter counts from 0000 to 9999 and then reset to zero and start again.

// Define Soft-SPI connections#define CS_PinGP0_bit#define MOSI_PinGP1_bit#define CLK_PinGP2_bitvoid SPI_Write_Byte(unsigned short num){unsigned short t, Mask, Flag;CLK_Pin = 0;Mask = 128;for (t=0; t<8; t++){Flag = num & Mask;if(Flag == 0) MOSI_Pin = 0;else MOSI_Pin = 1;CLK_Pin = 1;CLK_Pin = 0;Mask = Mask >> 1;}}void MAX7219_INIT() {// Disable Shutdown modeCS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(0x0C);// Select Shutdown registerSPI_Write_Byte(0x01);// Set D0 bit to return to normal operationCS_Pin = 1;// CS pin is pulled HIGH// Set BCD decode mode for digits DIG0-DIG3CS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(0x09);// Select Decode Mode registerSPI_Write_Byte(0x0F);// Select BCD mode for digits DIG0-DIG3CS_Pin = 1;// CS pin is pulled HIGH// Set display brighnessCS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(0x0A);// Select Intensity registerSPI_Write_Byte(0x0F);// Set maximum brightnessCS_Pin = 1;// CS pin is pulled HIGH// Set display refreshCS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(0x0B);// Select Scan-Limit registerSPI_Write_Byte(0x03);// Select digits DIG0-DIG3CS_Pin = 1;// CS pin is pulled HIGH// Enable Display-TestCS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(0x0F);// Select Display-Test registerSPI_Write_Byte(0x01);// Enable Display-TestCS_Pin = 1;// CS pin is pulled HIGHDelay_ms(1000);// Disable Display-TestCS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(0x0F);// Select Display-Test registerSPI_Write_Byte(0x00);// Disable Display-TestCS_Pin = 1;// CS pin is pulled HIGH}void Display_Counter(unsigned int j){CS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(4);// Send thousands digitSPI_Write_Byte((j/1000)%10);CS_Pin = 1;// CS pin is pulled HIGHCS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(3);// Send hundreds digitSPI_Write_Byte((j/100)%10);CS_Pin = 1;// CS pin is pulled HIGHCS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(2);// Send tens digitSPI_Write_Byte((j/10)%10);CS_Pin = 1;// CS pin is pulled HIGHCS_Pin = 0;// CS pin is pulled LOWSPI_Write_Byte(1);// Send ones digitSPI_Write_Byte(j%10);CS_Pin = 1;// CS pin is pulled HIGH}unsigned short i;unsigned int counter = 0;void main() {TRISIO=0b00001000;// GP3 is input onlyCMCON0 = 0x07;ANSEL = 0x00;MAX7219_INIT();// InitializeMAX7219do{for (counter=0; counter<10000; counter++) {Display_Counter(counter);Delay_ms(1000);}}while(1);}

Download source and HEX files

The PIC12F683 microcontroller runs at 4.0 MHz internal clock and MCLR is disabled. In the picture below, the tiny PIC12F683 board is from iCircuit Technologies.

4-digit UP-counter using PIC12F683

The LED display module can also be interfaced with Arduino board using the LedControl library.

Interfacing with Arduino

Summary

This MAX7219 based LED display module allows you to interface a 4-digit 7-segment LED display to low-pin count microcontrollers using only three I/O pins. It gives you full control of all digits, decimal points, and the display brightness.

This display module is available for purchase as a kit. The price of the kit is $10.99 and includes free shipping (regular USPS) within the continental United States. The payment will be through Paypal. If you want this kit, email me first at admin (at) embedded-lab.com, and I will send you my Paypal information.

The picture below shows what you will get in the kit. A 5-pin male header (straight) is included in the kit. Here are the assembly instructions.

4-digit serial seven segment LED display kit

[via: http://embedded-lab.com/]

 

A digitalmultimeter is a very useful instrument that combines several measurement functions in one unit. A typical multimeter includes features of a variable-range ohmmeter, voltmeter, and ammeter. Some of them also include capabilities of testing diodes and transistors. In this article, I am going to talk about a technique of adding thermometer feature to a regular digital multimeter. The technique is very simple and uses one temperature sensor along with two resistors and a DPDT slide switch.

Multimeter showing the surrounding temperature in degree Celsius

Theory

In my previous article (Testing analog temperature sensors with a multimeter), I described a method of using a multimeter to test analog temperature sensors like LM34, LM35, MCP9701, TMP35, etc. These sensors provide an analog output voltage that is linearly proportional to the temperature, and therefore, by measuring the output voltage with a multimeter, we can verify if the sensor is working or not. Now we are going to embed one such sensor inside a digital multimeter and use the voltmeter feature of the meter to display temperature on the LCD. The sensor will acquire power supply from the multimeter circuit itself. Although this sounds pretty simple, there are few issues that must be taken care of to make it work.

Let’s look at the setup shown in the picture below. Here, the LM35 sensor is powered from an external 9V battery source and its output is measured with a digital multimeter setup as a voltmeter. The LM35 output is linearly proportional to the Celsius temperature with a scaling factor of +10mV/°C, which means if the temperature is 24.5°C, the multimeter will measure the sensor output as 245 mV. Now the question is will the multimeter output be the same if the LM35 sensor is placed inside the multimeter and powered from the same battery (usually 9V or 12V) that is powering the multimeter? Actually,it is not. Let’s see why.

LM35 output voltage is proportional to centigrade temperature

Most of the inexpensive digital multimeters available in the market are based on ICL7106 chip, which is a low power A/D converter with a built-in 3 1/2 digit LCD display driver. The maximum voltage that can be applied between its power supply pins, V+ and V-, is +15V. However, the multimeters based on this chip are usually seen to be powered by either a 9V PP3 or a 12V A23 battery. Now if the LM35 sensor uses the same battery to power itself, then it will use the negative terminal of the battery as the reference point (ground) to generate the output voltage, which is proportional to the temperature. But the ICL7106 A/D converter does not measure the input voltage with reference to the negative terminal of the battery. Instead, it uses a separate reference voltage (known as common terminal, or COM point) which is derived from the supply voltage and is set somewhere between V+ and V-. The multimeter has two leads: red and black. The black lead goes to the COM terminal (which is the reference point) and the red lead goes to the IN+ terminal of the multimeter circuit. The voltage at IN+ is appropriately scaled (based on the selected range) through an on-board circuit before it is fed to the input of the ICL7106 A/D converter, which then measure it with reference to the COM voltage. The easiest way to find out the voltage of the COM terminal is to set the multimeter as voltmeter and connect the IN+ terminal (red lead) to the positive terminal of the battery as shown below.

COM and IN+ terminals inside the multimeter

The multimeter will show this voltage around 3V, which means the COM terminal is set to 3V lower than the battery’s positive voltage. I have tested this with a few other digital multimeters and they all show that the COM terminal is 3V lower than the battery’s positive terminal.

Potential difference between the positive terminal of the battery and the COM terminal is 3.0 V

Imagine what would happen if you connect the ground pin of the temperature sensor to the COM lead, instead of the negative terminal of the battery. The sensor will now provide output with reference to the COM terminal and the multimeter will be able to measure the sensor output correctly. But, unfortunately, the LM35 sensor does not operate at 3V. The recommended supply voltage range for LM35 is 4-30 V. But there are other similar sensors that operate at 3V, such as TMP35, which is functionally compatible with the LM35 sensor and operates at a single-supply voltage from 2.7 V to 5.5 V. It also does not require any external calibration to provide typical accuracies of ±1°C at +25°C and has an output scale factor of 10 mV/°C. However, the TMP35 reads temperature only from 10°C to 125°C.

Now we have resolved the reference voltage problem, and found a temperature sensor that operates at 3V. The next thing required is a divide-by-ten circuit. There is a factor of 10 in the sensor’s output voltage (mV) which must be taken out to get the actual temperature (°C). The divide-by-ten circuit can be simply constructed using two resistors (1.8K and 200Ω) connected in series as a voltage divider. The voltage across the 200Ω resistor is 1/1o th of the total voltage applied across the series combination of the two. The complete circuit diagram of this setup is shown below. A DPDT slide switch is included in the circuit to turn the thermometer on and off. When the switch is turned on, two things happen:

1. The TMP35 gets power supply.

2. The divided sensor output is connected to the IN+ terminal of the battery.

If you set the multimeter to measure voltage ranging from 0-200 mV, the temperature in °C will be displayed on the LCD screen.

 

Circuit diagram

In the circuit above, when the switch is turned off, the sensor’s power supply is cutoff, which is important because we don’t want the sensor to draw current from the battery all the time, and the multimeter’s IN+ terminal is disconnected from the sensor so that the multimeter can resume its normal operation.

Here’s my TMP35 sensor with the divide-by-ten network. I didn’t have a 200Ω resistor so I cascaded two 100Ω resistors.

Sensor and the resistive voltage divider network

Circuit placed inside the multimeter

I fixed the slide switch next to the battery compartment as shown below.

DPDT slide switch

After the circuit is placed inside the multimeter, put its cover back. Turn the multimeter knob to measure DC voltage between 0-200 mV, and push the slide switch to ON position. The sensor gets powered and its output is connected to the IN+ terminal of the multimeter. The meter then displays the temperature (°C) on the LCD screen.

Displaying room temperature in ° C

The following picture shows the temperature when the meter is placed inside refrigerator. It would probably go further down but I took it out after a couple minutes as the TMP35 can read temperature only above 10°C.

Meter placed inside the refrigerator

Now my multimeter has an added feature of displaying the ambient temperature on its LCD. How about yours?

I hope you enjoyed reading this!

[via: http://embedded-lab.com/]

 

There are quite a variety of active analog temperature sensor ICs that provide an output voltage proportional to the temperature. They usually don’t require any external calibration and signal conditioning, and as such their output can be directly fed to the input of an ADC for digital processing. A few examples of such sensors are LM34, LM35, TMP35/36/37, and MCP9701. If you are having any trouble using any of these sensors in your project, here is a quick way to test if your sensor is working or not.

Testing analog temperature sensor ICs with a multimeter

The technique is very simple. These sensors give analog output voltage proportional to the temperature. You can use a multimeter as a low range voltmeter and measure the output to see if it is giving you the right output voltage corresponding to the room temperature, as specified in their datasheets. You can also give some of your body heat by putting a finger over the sensor and see if the output voltage increases accordingly. Lets take an example of the LM34 sensor, whose output voltage is proportional to the Fahrenheit temperature. The temperature-to-voltage conversion factor is +10.0 mV/°F, which means if the surrounding temperature is 75 °F, the LM34 output will be 750 mV. LM34 operates from 5 to 30V, so you can power it directly with a 9V battery. The figure below shows the setup for testing the LM34 sensor using a multimeter. The multimeter is setup as a 0-2000 mV range voltmeter. Whatever displayed on the meter, if divided by 10, will give you the Fahrenheit temperature. Isn’t this one of the simplest ways of constructing a digital thermometer?

Test setup for LM34 sensor

Here are some snapshots that I took while testing the LM34 and LM35 sensors.

LM34 output shows the temperature is 74.2 °F

Now place your finger over the sensor and watch is the output goes up due to your body temperature, which is higher than the room temperature. If it does then the sensor is doing its job correctly.

Sensor output goes up if you touch it with a finger (showing 81.4 °F)

The output voltage of LM35 will be lower because they are calibrated in Celsius scale with a conversion factor of +10 mV/°C.

LM35 is calibrated in Celcius scale (shows 24.0°C)

If you want to try this with other sensors, please confirm their supply voltage range. Not all analog temperature sensors operate at such a wide supply range.

[via: http://embedded-lab.com/]

 

Chris (from PyroElectro) has posted an article on interfacing an external ADC chip to FPGAs and CPLDs, which do not have A/D capabilities built-in. He illustrates the idea with an Altera EPM7128 and a MAX150 8-bit analog to digital converter IC. The test analog signal is derived using a potentiometer and the converted digital output is shown using an LED bargraph display. The interface between the CPLD and ADC has been implemented in VHDL.

Interfacing an ADC to CPLD

[via: http://embedded-lab.com/]

 

A servo motor is a special geared DC motor equipped with an electronic circuit for controlling the direction of rotation, as well as the position, of the motor shaft. Because servo motors allows precise angular positioning of their output shaft, they are used extensively in robotics and radio-controlled cars, airplanes, and boats to control the motion of their various parts. In this lab session, we will first explore what a servo motor consists of and how it works and then illustrate how to interface it with a PIC microcontroller.

Servo motor control using PIC microcontroller

Theory

A servo motor (or servo) is a little box that contains a DC motor, an output shaft (servo arm) which is connected to the motor through a series of gears, and an electronic circuit to control the position of the shaft. The objective of using a servo is to achieve precise angular positioning of an object.

In order to accomplish a servo function, an instantaneous positioning information of the output shaft is fed back to the control circuit using a transducer. A simplest way of doing this is by attaching a potentiometer to the output shaft or somewhere in the gear train. The control electronics compares the feedback signal (which contains the current position of the shaft) from the potentiometer to the control input signal (which contains information of the desired position of the shaft), and any difference between the actual and desired values (known as an error signal) is amplified and used to drive the DC motor in a direction necessary to reduce or eliminate the error. The error is zero when the output shaft gets to the desired position. The functioning block diagram of a typical servomotor is shown below.

Principle of a servomotor

Servo parts (Source: http://tutorial.cytron.com.my/2011/09/19/how-rc-servo-works/)

The control input to a servo is a pulse width modulated (PWM) signal, generally of frequency 50 Hz. This means the pulse should repeat every 20ms. The width of the pulse determines the angular position of the output shaft. An electronic circuit inside the servo converts the PWM signal to a proportional output voltage which is compared with the feedback voltage from the potentiometer. If a difference exists between the two, the control circuit drives the motor in an appropriate direction until the difference becomes zero. A typical value of the pulse width is somewhere in the range of 1.0 to 2.0 milliseconds (ms). For a standard servo, a pulse width between 1.0 ms to 1.5 ms makes the servo to turn clockwise (CW), between 1.5 ms to 2.0 ms makes it to turn counterclockwise (CCW), and a 1.5 ms pulse width turns the servo motor to its center. However, these values could vary depending on the brand and make of the motor. It is advised to read the datasheet of the servo to find the true values of the pulse widths required for positioning the servo at different angles.

Most servos rotate through 180°. However. there are some that could rotate through a full 360° or more. Servos are widely used as the moving joints in robotic arms for their precise angular positioning. They also finds applications in radio controlled (RC) toys. For example, in RC cars they are used in the steering mechanisms, and in RC boats to control the rudder.

A servomotor has three wires: two are designated for power supply (Vcc and Ground) and the third wire is for the control signal.The Vcc wire is usually red and the ground one is either black or brown. The control signal wire comes in white, yellow, or orange color. The servomotor used in this experiment is from iCircuit technologies and has red, brown, and yellow color wires for Vcc, Gnd, and control signal, respectively. It operates at 5.0 V power supply and provides angular rotation through 180°

A typical servo motor

The pulse width values for different angular positions of this servo are provided in the table below. Remember that the repetition rate of the pulse should be 50 Hz (period of 20 ms).

Servo timing information for different anglular positions

Different angular positions of the servo arm

Circuit

The circuit diagram of this experiment is depicted below. The control input for the servo is derived from the RB1 pin of the PIC16F628A microcontroller that operates at 4.0 MHz using an external ceramic resonator. A tact switch is connected to the RB0 pin to provide user input to control the position of the servo arm. The operation part of this experiment is described in the software section below.

Circuit diagram for servo motor control demonstration

Circuit setup on breadboard

Software

The firmware for PIC16F628A is written in MikroC Pro for PIC compiler. The Timer0 module is operated as timer with prescaler 1:256 to generate an approximate 20 ms gap between the two successive PWM pulses. Keep in mind that the clock frequency is 4.0 MHz, which results into 1 μs machine cycle, thus simplifying the math involved in calculating the delay using Timer0. MikroC provides a built-in library function, Delay_Cyc(), that generates a variable clock cycles delay. This function is used to vary the width of the control pulse from 0.7 to 2.3 ms. When the circuit is first powered up or reset, a 50 Hz PWM signal with 0.7 ms pulse width is continuously generated at RB1 pin. This control signal moves the servo arm clockwise all the way to the end, which is considered as 0 angular position. When the tact switch connected to the RB0 pin is pressed, the width of the pulse is increased by 0.2 ms, which turns the shaft counterclockwise (CCW) by approximately 22.5°. So each time the switch is pressed, the pulse width is increased by 0.2 ms, and the shaft further rotates in CCW direction. After 8 successive presses of the switch, the pulse width becomes 2.3 ms and the shaft reaches the other end (180° angular position). On 9th press, the pulse width is reset to 0.7 ms, and the motor shaft rotates in clockwise direction until it gets at 0 angular position back.

/*Lab 21: Servo motor Control using PIC16F628AMCU: PIC16F628A running at 4.0 MHz, MCLR enabled, WDT is OFF, Brown out detect disabledWritten by: Rajendra Bhatt (www.embedded-lab.com)2012/03/29Description: User input switch is connected to RB0 and Servo Control signalis generated from RB1 pin.*/sbit SW1 at RB0_bit;sbit Control at RB1_bit;unsigned short i=7, delay;void interrupt() {delay = i*10;Control = 1;Delay_Cyc(delay);// Generates delay equal to (10*delay) clock cyclesControl = 0;TMR0 = 180;// TMR0 returns to its initial valueINTCON.T0IF = 0;// Bit T0IF is cleared so that the interrupt could reoccur}void main() {CMCON = 0x07;// Disable ComparatorsTRISB = 0b00000001;PORTB = 0;OPTION_REG = 0x07; // Prescaler (1:256) is assigned to the timer TMR0TMR0 = 180;// Timer T0 counts from 180 to 255 to create ~20 ms periodINTCON = 0xA0;// Enable interrupt TMR0 and Global Interruptsdo{if(!SW1){// Change pulse width when Switch is pressedDelay_ms(300);i = i+2;if(i>23) i=7;}}while(1);}

Download complete source and HEX files

Output

After loading the HEX file into the PIC16F628A microcontroller, you can watch the servo controller in action. Watch the demo video at the bottom to see the output of this experiment.

Servo control

[via: http://embedded-lab.com/]

 

Ibrahim Kamal from IKALOGIC informed me about his latest article on the use of CMOS camera for sensing applications posted on his website. It’s true that interfacing a CMOS camera with 8-bit microcontrollers has not been very common. There’s a stereotype that much faster and powerful microcontrollers are required to process the output of a CMOS camera, which may not always be true, as illustrated by Ibrahim Kamam. In fact, it all depends on the type of application you choose with a CMOS camera.

CMOS camera can replace an array of photo sensors

The article discusses about the possibility of using a CMOS camera for sensing applications by reducing the image resolution and getting rid of the color information. The downgraded image requires lesser computation, and therefore, is feasible to process using a simple 8-bit microcontroller. With this arrangement one CMOS camera could replace an array of conventional light sensors (made of LEDs and photodiodes) that are used in many embedded applications including robotics. A quick illustration on how to interface the TCM8230MD CMOS camera (available from SparkFun) to an AVR XMEGA processor has also been discussed in the article.

[via: http://embedded-lab.com/]

 

In his digital light meter project, Shawon Shahryiar demonstrated a technique of using a normal LDR to construct a simple LUX meter that outputs the ambient light conditions on an LCD display. While this technique is simple and cost-effective, it requires an additional reference photometer to calibrate the LDR first adding an additional step. I came across this another LUX meter project on University of Wisconsin-Superior websitethat eliminates the need of external calibration and provides very precise measurement of illuminance in the range of 0.025 – 99999 LUX.

Digital LUX meter using MAX44007 (Source: http://mcs.uwsuper.edu/sb/Electronics/Lux/)

This project uses Maxim’s MAX44007 ambient light sensor which features an integrated photodiode with onboard ADC and I²C digital output. The sensor is designed to operate from a 1.7V to 3.6V supply voltage and consumes only 0.65µA in full operation. It has an extremely large dynamic light range that extends from 0.025 lux to 104,448 lux. The microcontroller used in this project is Silicon Laboratories C8051F304, but the sensor can be interfaced to any other microcontroller with I2C capability.

[via: http://embedded-lab.com/]

 

There is a good news for PIC fans. Microchip Technology, Inc. has recently announced the expansion of its 8-bit enhanced Mid-range core microcontroller (MCU) family to include advanced analog and digital integration, such as 12-bit A/D converter, 8-bit DAC, Op-Amps with Rail-to-Rail input/output, and high-performance Rail-to-Rail comparators.

Key peripherals in the new 8-bit PIC MCUs

CHANDLER, Ariz., March 26, 2012 [NASDAQ:MCHP] — Microchip Technology Inc., a leading provider of microcontroller, analog and Flash-IP solutions, today announced from DESIGN West in San Josethe expansion of its 8-bit PIC16F(LF)178X enhanced Mid-range core microcontroller (MCU) family to include advanced analog and integrated communication peripherals, such as on-chip 12-bit Analog-to-Digital Converters (ADCs), 8-bit Digital-to-Analog Converters (DACs), operational amplifiers, and high-speed comparators, along with EUSART (including LIN), I2C™ and SPI interface peripherals.The MCUs also feature the industry’s best level of advanced PWM control and accuracy via the new Programmable Switch-Mode Controllers (PSMCs).This combination of features enables higher efficiency and performance, along with cost and space reductions in applications such as closed-loop control in power supplies, and lighting.The “LF” versions of the MCUs feature eXtreme Low Power Technology, for active and sleep currents of just 32 µA/MHz and 50 nA, respectively, helping to extend battery life and reduce standby current consumption.Low power consumption and advanced analog and digital integration make the general-purpose PIC16F(LF)178X MCUs ideal for LED lighting, battery management, digital power supply, motor control and other applications.

More details of the story can be found here.

[via: http://embedded-lab.com/]

 

Capacitors are one of the most common passive electrical components that are extensively used in all kinds of electronic circuits. In this project, we will discuss a technique of building a digital capacitance meter using a PIC microcontroller. This project can measure capacitance values from 1 nF to 99 μF, with a resolution of 1 nF. The technique is based on measuring the charging time of a capacitor which is related to its capacitance value. The microcontroller used in this project is PIC16F628A.

Capacitance meter

Theory

This capacitance meter is based on the principle of charging a capacitor through a series resistor. In a series RC circuit, as shown in the figure below, the voltage across the capacitor increases exponentially as it charges. Lets assume that initially the capacitor was fully discharged. When Vin is applied across the RC circuit, the capacitor starts charging and consequently, the voltage (Vc) across it increases from 0 towards Vin in an exponential way, as shown in the right side of the figure. The equation provided in the figure describes how the voltage across the capacitor changes with time. If we know the time that is required for the capacitor to charge up to a known voltage then we can solve this equation for C, knowing the value of R.

Capacitor voltage increases exponentially with time

The idea of measuring time elapsed when the capacitor is charged to a known voltage can be implemented with any microcontroller. Here, we are using the PIC16F628A microcontroller, which has two built-in analog comparator0s. In this project, we are using the Analog Comparator 2 and TIMER2 modules to determine the time required by the capacitor to charge from 0V to 0.5Vin. The positive and negative inputs of the Analog Comparator 2 are externally accessible through RA2 and RA1 pins of PIC16F628A, respectively. In the figure shown below, two 2.2K resistors creates a voltage divider that sets the positive input (RA2) of the comparator to half of the voltage applied to RA0 pin. The negative input (RA1) of the comparator goes to the positive end of the capacitor through a 330Ω resistor. The resistor is used to discharge the capacitor by setting RA1 low prior to its measurement. When a voltage is applied to the RA0 pin, the capacitor, initially fully discharged, is charged through a 22K resistor. Initially, when the RA0 pin is just set high (say around 5V), the output of the comparator is high as the positive input of the comparator is at higher voltage (about 2.5V) than the negative input, which is close to 0V as the capacitor is fully discharged. Now the capacitor starts charging through the series resistor (22K) and when the voltage across it exceeds half of the voltage at RA0 pin, the comparator output is flipped to low. The Timer2 module is used to compute the time elapsed during the process.

RC circuit and comparator inputs

By knowing the value of the charging resistor (in this case it is 22K) and the charging time (from Timer2), we can now solve the capacitor equation, mentioned above, to compute C. Here’s the mathematics involved in the process. For simplicity, the Timer2 is initialized with value 104 so that it overflows in 256-104=152 clock cycles. If we use 4.0 MHz external clock source, this is equivalent to 152 μsec. By doing so, the calculations are much simplified as described below. The final equation suggests that the capacitance in nF is simply 10 multiplied by the number of times the Timer2 overflows starting from 104 every time. A further improvement in the resolution is obtained by further considering the value of Timer2 at the instant when the comparator output switches to low. This gives the resolution of 1nF.

Calculating C from charging time

Capacitance meter circuit

sdsdsd

Voltage divider and RC circuit

Complete setup of the experiment

dfdsf

Software

asasas

 /*Project: Capacitance meterDescription : CapMeter based on RC time constantMCU: PIC16F28AOscillator: HS, 4.0000 MHz externalWritten by: Rajendra Bhatt (www.embedded-lab.com)*/// LCD module connectionssbit LCD_RS at RB2_bit;sbit LCD_EN at RB3_bit;sbit LCD_D4 at RB4_bit;sbit LCD_D5 at RB5_bit;sbit LCD_D6 at RB6_bit;sbit LCD_D7 at RB7_bit;sbit LCD_RS_Direction at TRISB2_bit;sbit LCD_EN_Direction at TRISB3_bit;sbit LCD_D4_Direction at TRISB4_bit;sbit LCD_D5_Direction at TRISB5_bit;sbit LCD_D6_Direction at TRISB6_bit;sbit LCD_D7_Direction at TRISB7_bit;sbit Va at RA0_bit;sbit Switch at RB0_bit;char message1[] = "Capacitance";char message2[] = "Meter";unsigned int T_Value, Num;unsigned short i, j, TimerValue, OverRange = 0;char Capacitance[] = "00.000 uF";char gOverTest = 0;char gMessage[8];char gCapstr[8];void interrupt(){if(PIR1.TMR2IF){TMR2 = TimerValue;Num ++;if(Num > 9999) OverRange = 1; // Range is 99.99 uFPIR1.TMR2IF =0; // Clear TMR0 interrupt flag}}void Display_Cap(unsigned int n){Capacitance[0] = n/10000 + 48;Capacitance[1] = (n/1000)%10 + 48;Capacitance[3] = (n/100)%10 + 48;Capacitance[4] = (n/10)%10 + 48;Capacitance[5] = (T_Value*10)/153 + 48;Lcd_Cmd(_Lcd_Clear);Lcd_Out(1, 1, "C = ");Lcd_Out(1, 5, Capacitance);}void reset(){TRISA = 0b00000100;CMCON = 7;RA1_bit = 0;Delay_ms(2000);TRISA = 0b00000110;CMCON = 5;}void main(){char cap_size;TRISB = 0b00000001;PORTB = 0;TRISA = 0b00000110;OPTION_REG.T0CS = 0;INTCON.GIE = 1; //Enable global interruptINTCON.PEIE = 1; //Enable peripheral interrupt// Configure Timer2 modulePIE1.TMR2IE = 1;// Enable Timer2 interruptT2CON = 0;// Prescaler 1:1, and Timer2 is off initiallyPIR1.TMR2IF =0;// Clear int bit// Configure Comparator moduleCMCON = 5;// Independent comparator between RA1 (-) and RA2(+)Lcd_Init();Lcd_Cmd(_Lcd_Clear);Lcd_Cmd(_LCD_CURSOR_OFF);Lcd_Out(1, 1, message1);Lcd_Out(2, 1, message2);delay_ms(2000);Lcd_Cmd(_Lcd_Clear);Lcd_Out(1, 1, "C = ");Lcd_Out(1, 5, Capacitance);Va = 0;TimerValue = 108;// 104 + 4 clock delay on branching to ISR and otherswhile(1){if(!Switch) {Num = 0;OverRange =0;Lcd_Cmd(_Lcd_Clear);Lcd_Out(1, 1, "Testing.");Lcd_Out(2, 1, "...");TMR2 = TimerValue;// Initial value of Timer2 for 30us delayVa = 1; //apply voltageT2CON.TMR2ON = 1; // start timerwhile(CMCON.C2OUT) {if(OverRange) break;}T2CON.TMR2ON = 0; // stop timerT_Value = TMR2 - TimerValue;Va = 0;//---------------------------------if(!OverRange){Display_Cap(Num*10);}else{OverRange = 0;Lcd_Cmd(_Lcd_Clear);Lcd_Out(1, 1, "Out of Range!");}reset();}}}

ww

Download complete source and HEX files

asasa

Measuring 1 nF rated capacitor

Measuring 15 nF rated capacitor

Measuring 100nF rated capacitor

Measuring 10 uF rated capacitor

Capacitor rated 22 uF

Capacitor greater than 100 uF

[via: http://embedded-lab.com/]

© 2011 Geko Geek This is a news aggregator website. Articles and images are copyrighted to their original source authors. Gekogeek takes no responsibility about the articles content Suffusion theme by Sayontan Sinha