Thursday, March 11, 2021

A DC +50V DVM using ADC of PIC16F887 MikroC

Input signal to ADC channel of a microcontroller is other than DC voltage source. It typically range from 0 to 5V DC, as a conventional microcontroller, and voltage reference of ADC module are around +5V. Measuring input voltage within this range is straight forward using a calculation of ADC result and its step voltage size.

A DC +50V DVM using ADC of PIC16F887 MikroC
A DC +50V DVM using ADC of PIC16F887 MikroC - Program sample
Embedded controller is able to measure input DC voltage exceeding this range - for example measuring an input voltage of +50V DC. From electric circuit theory, voltage divider circuit divides input voltage source to lower output using two resistors.



Reference circuit from Wikipedia

Dividing factor depends on value of these two resistor that we can not give its detail and formula here. Using this method we can design a simple digital volt meter (DVM) with a maximum range of +50V DC.

In this example we select Z1 = 100kOhm and Z2 = 10kOhm. This circuit gives an output dividing factor of 0.09 at Vout. So whenever input voltage Vin = 50V then output voltage 50V * 0.09 that is around 5V, which is the maximum input voltage to ADC input channel.

A DC +50V DVM using ADC of PIC16F887 MikroC
Circuit Diagram

In this program timer0 is used to schedule ADC reading before it's converted to actual DC input voltage. Using its 8MHz internal oscillator source, timer0 interrupt creates a timer tick for scheduling ADC reading. Whenever the total tick equal to 30 it's a one second timing. Hence ADC reading is activated for every 30 timer0 tick (one second).

However multiplexing display doesn't use this timer tick due total lines of C source code.

MikroC source code:

  1. #define STEP_SIZE 0.0048
  2. #define ONE_SECOND 30
  3. #define RATE 3
  4. #define DIGIT1 PORTA.RA4
  5. #define DIGIT2 PORTA.RA5
  6. #define DIGIT3 PORTA.RA6
  7. #define DIGIT4 PORTA.RA7
  8.  
  9. unsigned ADC_Value,V_Measure;
  10. float Voltage;
  11. char int_count;
  12. char LED[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  13. bit ADC_RUN;
  14.  
  15. void interrupt() {
  16. if(INTCON.T0IF) {
  17. int_count++;
  18. if(int_count==ONE_SECOND)
  19. { int_count=0; ADC_RUN=1; }
  20. }
  21. INTCON.T0IF=0;
  22. }
  23.  
  24. void PORT_SETUP() {
  25. PORTA=0x00;
  26. PORTB=0x00;
  27. TRISA=0x01; // RA0 IS ANALOG IN PUT
  28. TRISB=0x00; // PORTB is OUTPUT
  29. ANSEL=0x01; // SELECT AN0
  30. ANSELH=0x00; // OTHERS ARE DIGITAL IO
  31. OSCCON|=0x07; // SELECT 8MHz INT RC
  32. }
  33.  
  34. void Timer0_Setup(){
  35. OPTION_REG.T0CS=0; // SELECT FOSC/4
  36. OPTION_REG.PSA=0; // SELECT TIMER0 PRESCALER
  37. OPTION_REG|=0x07; // SELECT 1:256 PRESCALER
  38. }
  39.  
  40. void interrupt_setup() {
  41. INTCON.GIE=1;
  42. INTCON.T0IE=1;
  43. INTCON.T0IF=0;
  44. }
  45.  
  46. void Read_Temp () {
  47. if(ADC_RUN=1) {
  48. ADC_Value=ADC_Get_Sample(0); // READ AN0
  49. delay_ms(10);
  50. Voltage=ADC_Value*STEP_SIZE; // Convert to Decimal [Volt]
  51. }
  52. ADC_RUN=0;
  53. }
  54.  
  55. void SSD() {
  56. V_Measure=Voltage*10/0.090; // convert Voltage to integer
  57.  
  58. PORTB=LED[V_Measure/100];
  59. DIGIT1=1;
  60. delay_ms(RATE);
  61. PORTA=0x00;
  62.  
  63. PORTB=LED[(V_Measure%100)/10]|0x80;
  64. DIGIT2=1;
  65. delay_ms(RATE);
  66. PORTA=0x00;
  67.  
  68. PORTB=LED[V_Measure%10];
  69. DIGIT3=1;
  70. delay_ms(RATE);
  71. PORTA=0x00;
  72.  
  73. PORTB=0x62;
  74. DIGIT4=1;
  75. delay_ms(RATE);
  76. PORTA=0x00;
  77. }
  78.  
  79. void main() {
  80. ADC_Value=0;
  81. int_count=0;
  82. ADC_RUN=0;
  83. PORT_SETUP();
  84. ADC_Init();
  85. Timer0_Setup();
  86. Interrupt_Setup();
  87. while(1) {
  88. Read_Temp();
  89. SSD();
  90. }
  91. }
 
Click here to download this example program.

No comments:

Post a Comment

Labels

ADC (10) Analog (14) Arduino (12) Atmega16 (19) Audio (2) AVR (20) Charger (1) Cortex-M0 (1) Counter (10) CPLD (25) Digital I/O (22) Display (34) EEPROM (2) Environment Sensor (1) esp8266 (2) Experiment Board (10) I2C (4) Interrupt (7) LCD (1) LDmicro (29) measurement and instrumentation (7) Microchip Studio (3) MikroC (1) One-Shot (3) OpAmp (1) PCB (31) PIC16 Microcontrollers (16) PIC16F877A (2) PIC16F887 MikroC (22) PLC (35) PWM (11) Regulator (1) RTC (2) Sensor (8) Shift Registers (5) SPI (5) Timer (34) UART (2) ultra-sonic sensor (1) USB (1) VHDL (21) xc8 (1) XC95108 (9) XC9536 (15) XC9572 (1) Xilinx (23) Xilinx ISE (22)