Download this article in .PDF format
This file type includes high resolution graphics and schematics when applicable.
When the need arises to convert voltage readings from an analog sensor into a pulse train, a low-end microcontroller offers a versatile solution. The design in Figure 1 uses an 8-pin PIC 12F683 to provide a pulse train that’s proportional to the sensed input voltage. This is useful, for example, when transforming a sensor signal into a format that’s compatible with a basic digital or GPIO input. The output operating range ranges between 0 to 500 pulses for an input voltage of 0 to 5.00 V dc.
An input voltage (VIN) of 1.25 V dc, for example, will generate a pulse train (Pt) of 125, which is defined by the equation:
Pt = VIN × 100
where VIN is in volts, decimals, and hundredths. In this design, each pulse has a period of 1 ms with a 50% duty cycle. The refresh time (Rt) is given by:
Rt = VIN x 1 ms + 50 ms delay
The longest refresh time of 0.499 seconds (plus 50-ms delay) occurs for a 4.99-V reading, while the shortest one of 51 ms corresponds to an input voltage of 0.01 V. The 50-ms delay added to all readings is needed to avoid a flickering display.
In the circuit, an analog input voltage delivered by a 47-kΩ trimming potentiometer is applied to the microcontroller’s analog Input (AN3). The internal analog-to-digital converter (ADC) is configured to 8 bits, providing a precision of ±19.60 mV, with a resolution of 100 mV.
To test the MCU program, the circuit includes a 3-digit BCD counter using an MC14553 (www.onsemi.com) to count the pulse train. The train is latched in the counter and decoded with a CD4543 to drive a four-digit multiplexed LED Display (Lite-On Inc. LTC-4727JR) via three switching transistors. Figure 2 shows the actual circuit assembled in a prototyping board.
To generate a pulse train on GP2 proportional to the input voltage, the algorithm (see the listing below) takes a voltage reading and makes a conversion to decimal with the LSB constant equal to 19.60. It then gets its equivalent in digital format for the units, decimals, and hundredths, using the instructions DIG3, DIG2, and DIG1, respectively. The DIG1 value is stored in variable “units” to create a loop that generates that number of pulses. Similarly, the DIG2 value is multiplied by 10 and stored in a variable called “decimals” to generate the tens of pulses. Finally, the DIG3 value is stored in the variable called “units,” which is multiplied by 100 to generate the hundreds of pulses required for the reading.
In this way, for example, a voltage reading of 2.54 V will be composed of 4, then 50, and then 200 pulses, to get a total of 254 pulses with a period of 1 ms. Therefore, it takes approximately 254 ms to transmit this pulse train. If one of the digits is equal to zero, the program skips that loop. Figure 3 shows a pulse train with its corresponding output generated by GP5.
Once the pulse train is finished, a 1-ms latch (active low) pulse on GP0 is transmitted to store that reading in the MC14553’s internal latches. Then a second (active high) 1-ms pulse on GP1 is generated to clear the counter to all zeroes (Fig. 4). The latch in the CD4543 decoder is set to transparent mode. Output GP5 is used to indicate when the MCU is transmitting the pulse train.
Three PNP transistors 2N2907 (Q1 to Q3), which continuously scan the data to the LED display, are controlled by the MC14553 counter. Transistor Q4 activates the decimal point, providing a 5-V pulse only when /DS1 is pulsed low. Figure 5 shows the 11 pulses generated for a voltage reading of 0.11 V dc, and the latch pulse generated at the end of the pulse train.
For higher-precision applications (such as 4.88 mV per LSB), you can configure the ADC to 10 bits. In this case, the output-signal period might be reduced to 0.5 ms to avoid having longer delays when the input voltage is at maximum. In such a case, a 1.000-V dc reading would generate 1000 pulses. For battery-operated applications, a numerical liquid-crystal display is recommended, which requires using three CD4543 decoders.
'*************************************************************** '* Name : VOLT-TO-PTRAIN-706-15.PBP * '* Authors : R. JIMENEZ, and Juan C. Angeles * '* Date : 7/03/2015 * '* GP0 is /LATCH, GP1 is RESET, GP2 is Pulse Train Output * '* Notes : AN3 is the Voltage Input with a renge of 0.00-4.99 Vdc. * '* VOLTAGE TO PULSE-TRAIN GENERATOR 12F683 W/CD4553 * '*************************************************************** ASM__CONFIG_MCLRE_OFF; GP3 Enabled as Input and /MCLR to Vdd WPU.3= 1; Pull-up Resistor in GP3 enabled to avoid floating pin VOLT VAR WORD: V1 VAR WORD: I VAR WORD UNITS VAR WORD: TENS VAR BYTE: CENTS VAR BYTE DECIMALS VAR BYTE VOLTS1 VAR WORD: VOLTS2 VAR WORD TRISIO= %011000; GP0:2 set as outputs, GP3:4 inputs, GP5 output ANSEL= %010000; AN3 set as Analog (pin 3) CMCON0= %00000111; CIN pins I/O, Comparator Off, Cout OFF OSCTUNE=0; OSCCON= %01100101; 4 MHz internal oscillator DEFINE ADC_BITS 8; A/D configuration DEFINE ADC_CLOCK 3; clock source DEFINE SAMPLEUS 50; wait 50 uS after acquisition time of 20 uS GPIO= %00001001; LE= H, RPT: GPIO.1=0; PAUSE 10; ADCIN 3, VOLT; read voltage on AN3, and store it on variable Volt MSR: VOLTS1 = VOLT * 19; convert binary to dec reading 19.60 VOLTS2 = VOLT * 60; VOLTS2 = VOLTS2/100; VOLT = VOLTS1 + VOLTS2; UNITS = VOLT DIG 3; getting the decimal equivalent digits DECIMALS = VOLT DIG 2; DIG3.DIG2 DIG1 0.00 -- 4.99 TENS = VOLT DIG 4; âUNITS DEC CENTSâ not required CENTS = VOLT DIG 1; DECIMALS= DECIMALS*10; UNITS= UNITS*100; ; ******************** converting reading to pulse train ***** IF CENTS= 0 THEN GOTO SKP1; 1/100 LOOP GPIO.5= 1; High time for pulse train FOR I= 1 TO CENTS; PAUSEUS 500; 0.5 mS Hight time GPIO.2=0; 0.5 mS Low time PAUSEUS 500; 1 mS X Cents NEXT I SKP1: IF DECIMALS= 0 THEN GOTO SKP2; 1/10 LOOP GPIO.5= 1; period pulse on GP5 FOR I= 1 TO DECIMALS; GPIO.2=1 ; PAUSEUS 500; GPIO.2=0; PAUSEUS 500; NEXT I SKP2: IF UNITS=0 THEN GOTO LR; 1/1 LOOP GPIO.5= 1; period pulse on GP5 FOR I= 1 TO UNITS GPIO.2=1 ; PAUSEUS 500; GPIO.2=0; PAUSEUS 500; NEXT I GPIO.5= 0; period pulse ends ; ********** /LATCH and RESET pulses for the counter MC14553 LR: GPIO.5= 0; period pulse on GP5 GPIO.0= 0; Latch 1 mS \_/ PAUSE 1; GPIO.0=1; Clear latch PAUSE 1 GPIO.1= 1; Reset 1 mS /=\ PAUSE 1; GPIO.1=0; Clear Reset PAUSE 50; wait 50 mS before taking a new reading GOTO RPT; END
Ricardo Jiménez is an adjunct professor in Electronics at Imperial Valley College, Imperial, Calif. He can be reached at [email protected].
Juan C. Ángeles is pursuing his associate degree in math and science at Imperial Valley College.