You are on page 1of 3

ACvoltmeter.

c
Long ago
17 Jun 2014
S
Syed Tahmid Mahbub created an item
C
ACvoltmeter.c
/*
* Programmer: Syed Tahmid Mahbub
* AC Voltmeter
* Target PIC: PIC16F676
*/

#define SA RC4_bit // 6
#define SB RC2_bit // 8
#define SC RC1_bit // 9
#define SD RC5_bit // 5
#define SE RA4_bit // 3
#define SF RC3_bit // 7
#define SG RC0_bit // 10
#define C1 RA5_bit // 2
#define C2 RA2_bit // 11
#define C3 RA1_bit // 12

#define vinCh 0 // RA0

unsigned int voltage;

unsigned char SEGMENT;


const unsigned char COMMON_CATHODE = 0;
const unsigned char COMMON_ANODE = 1;
const unsigned char COMMON = COMMON_CATHODE;
unsigned char DriveSegment[10];

const unsigned char AnodeDriveSegment[10] = {192, 249, 164, 176, 153, 146, 130,
248, 128, 152};
/* These are the values that need to be sent to the seven segment [A..G] for
* a common anode display. These values have been obtaned using the
* Mikroelektronika seven segment editor provided as part of the
* mikroC/mikroBASIC/mikroPASCAL compiler.
* The corresponding values for the common cathode display are:
* CathodeDriveSegment = 255 - AnodeDriveSegment;
*/

void initialize(void){
unsigned char i;

CMCON = 7; // For 16F676 - comment for 16F684


// CMCON0 = 7; // For 16F684 - comment for 16F676
TRISA = 1; // RA0 input for ADC
PORTA = 0;
ANSEL = 1;
ADC_Init();

TRISC = 0;
PORTC = 0;

if (COMMON == COMMON_ANODE){
for (i = 0; i < 10; i++){
DriveSegment[i] = AnodeDriveSegment[i];
}
}
else{
for (i = 0; i < 10; i++){
DriveSegment[i] = 255 - AnodeDriveSegment[i];
}
}

unsigned int getVoltage(void){


unsigned int vADC;
float realVolts;
unsigned int fullRange = 600; // 600VDC = ~424VAC
/* DC (AC * sqrt(2)) voltage when ADC input voltage = 5.00V
* This is essentially the "max" voltage of the voltmeter
*/
vADC = ADC_Get_Sample(vinCh);
realVolts = ((float)vADC * (float)fullRange) / (1024.0 * 1.41421);
return (unsigned int) realVolts;
}

void displayVoltage(void){
unsigned int SendVal;
unsigned char Digit;
unsigned char counter;

for (counter = 0; counter < 3; counter++){ // repeat for each segment


SEGMENT++;
if (SEGMENT > 3) SEGMENT = 1;

C1 = 0; C2 = 0; C3 = 0;

switch (SEGMENT){
case 1:
Digit = (unsigned char) (voltage / 100);
break;
case 2:
Digit = (unsigned char) ((voltage / 10) % 10);
break;
case 3:
Digit = (unsigned char) (voltage % 10);
break;
}

SendVal = DriveSegment[Digit] & 0x7F; // Make bit 7 zero

SA = SendVal & 1; // bit 0


SB = (SendVal & 2) >> 1; // bit 1
SC = (SendVal & 4) >> 2; // bit 2
SD = (SendVal & 8) >> 3; // bit 3
SE = (SendVal & 16) >> 4; // bit 4
SF = (SendVal & 32) >> 5; // bit 5
SG = (SendVal & 64) >> 6; // bit 6

switch (SEGMENT){
case 1:
C1 = 1;
break;
case 2:
C2 = 1;
break;
case 3:
C3 = 1;
break;
}

delay_ms(2);
}
}

void main(void) {

char samplecounter;

initialize();
while (1){
voltage = getVoltage();
for (samplecounter = 0; samplecounter < 80; samplecounter++){
displayVoltage();
}
}
}

You might also like