ADE7758 and ATmega32

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Friends

Hi and good day

I'm have started a project aiming energy metering of my electrical devices . I want to measure the Power consumption (watt/var). The IC that I use is ADE7758 (although I don't need 3 phase measuring ) and have designed a PCB for it .

I'm  working with CV(codevision 2.5.3) but found a very useful project in the following link which is in winavr . 

http://www.vabolis.lt/stuff/2012...

Has any one worked with ADE7758 in CV yet?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I saw that this code request has been posted several times during recent years . someone may have finished it 

can anyone help me ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

OP posted above per my suggestion, following PMs.  While I have posted ADE7754 and ADE7763 code, it has been some years ago and Web site "improvements" have truncated code postings and otherwise made them unreadable.  So I'll do some digging, and repost some fragments.

 

IMO/IME, ADE77xx devices with the SPI interface follow a very similar pattern.  It isn't a trival driver, though, as there are 8/16/24/32 bit values and many registers.

 

But the devices work well, as they are suitable for energy billing.  And that commodity market means that we can design-in at a very reasonable cost.

 

Caveat 1:  I haven't worked with them for about 10 years.  There may well be new generations.

Caveat 2:  Voltage measurements are normally made with dropping resistors.  If you don't know what "this device floats on the mains" means, then you shouldn't be messing with it.  (Same with current, but we used CTs.)  Yes, one can use an isolation transformer for the V but that introduces its own complications.  We went with direct dropping resistors for the V, and isolated the comms and other interfaces to the outside world.

 

'7754 device:  http://www.anderson-bolds.com/Me...

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

ADE7763 excerpts.  Note that the read/write primitives are straightforward SPI work.  The trick is the table that gives the width of the piece of information being acted upon.  A few usage fragments at the end of "driver".

 

reg7763.h

//
//	Analog Devices ADE7763 Energy Meter Chip
//	****************************************
//
//	MR_ = Meter Register
//
//	In general, names and abbreviations are as used in ADE7763 data sheet
//

//
//	Register Address Definitions
//

#define	MR_Reserv00		0x00
#define	MR_WFORM        0x01
#define	MR_AENERGY      0x02
#define	MR_RAENERGY     0x03
#define	MR_LAENERGY     0x04
#define	MR_VAENERGY     0x05
#define	MR_RVAENERGY    0x06
#define	MR_LVAENERGY    0x07
#define	MR_Reserv08     0x08
#define	MR_MODE         0x09
#define	MR_IRQEN        0x0A
#define	MR_STATUS       0x0B
#define	MR_RSTATUS      0x0C
#define	MR_CH1OS        0x0D
#define	MR_CH2OS        0x0E
#define	MR_GAIN         0x0F
#define	MR_PHCAL        0x10
#define	MR_APOS         0x11
#define	MR_WGAIN        0x12
#define	MR_WDIV         0x13
#define	MR_CFNUM        0x14
#define	MR_CFDEN        0x15
#define	MR_IRMS         0x16
#define	MR_VRMS         0x17
#define	MR_IRMSOS       0x18
#define	MR_VRMSOS       0x19
#define	MR_VAGAIN       0x1A
#define	MR_VADIV        0x1B
#define	MR_LINCYC       0x1C
#define	MR_ZXTOUT       0x1D
#define	MR_SAGCYC       0x1E
#define	MR_SAGLVL       0x1F
#define	MR_IPEAKLVL     0x20
#define	MR_VPEAKLVL     0x21
#define	MR_IPEAK        0x22
#define	MR_RIPEAK       0x23
#define	MR_VPEAK        0x24
#define	MR_RVPEAK       0x25
#define	MR_TEMP         0x26
#define	MR_PERIOD       0x27
#define	MR_Reserv28     0x28
#define	MR_Reserv29     0x29
#define	MR_Reserv2A     0x2A
#define	MR_Reserv2B     0x2B
#define	MR_Reserv2C     0x2C
#define	MR_Reserv2D     0x2D
#define	MR_Reserv2E     0x2E
#define	MR_Reserv2F     0x2F
#define	MR_Reserv30     0x30
#define	MR_Reserv31     0x31
#define	MR_Reserv32     0x32
#define	MR_Reserv33     0x33
#define	MR_Reserv34     0x34
#define	MR_Reserv35     0x35
#define	MR_Reserv36     0x36
#define	MR_Reserv37     0x37
#define	MR_Reserv38     0x38
#define	MR_Reserv39     0x39
#define	MR_Reserv3A     0x3A
#define	MR_Reserv3B     0x3B
#define	MR_Reserv3C     0x3C
#define	MR_TMODE        0x3D
#define	MR_CHKSUM       0x3E
#define	MR_VERSION      0x3F

//
//	MR_GAIN register bits
//
//	High 3 bits are voltage (channel 2) gain
//	Middle two bits are full-scale select for current (channel 1)
//	Low 3 bits are current (channel 1) gain
#define	MR_GAIN_V1		0X00
#define	MR_GAIN_V2		0X20
#define	MR_GAIN_V4		0X40
#define	MR_GAIN_V8		0X60
#define	MR_GAIN_V16		0X80

#define	MR_GAIN_FS_HALF			0X00	// 0.5V
#define	MR_GAIN_FS_QUARTER		0X08	// 0.25V
#define	MR_GAIN_EIGHTH			0X10	// 0.125V

#define	MR_GAIN_I1		0X00
#define	MR_GAIN_I2		0X01
#define	MR_GAIN_I4		0X02
#define	MR_GAIN_I8		0X03
#define	MR_GAIN_I16		0X04


//
//	MODE register bits
//
//	There are valid combinations of the SWAP and A/D disable functions,
//	which would not be used during normal operation.
//
//	ADE7763 default at power-up:  0x000C ==>  DISCF + DISSAG
//
#define	MR_MODE_DISHPF			0x0001	//	High-pass filter HPF1 disabled when set
#define	MR_MODE_DISLPF2			0x0002	//	Low-pass filter LPF2 disabled when set
#define	MR_MODE_DISCF			0x0004	//	CF output disabled when set (default)
#define	MR_MODE_DISSAG			0x0008	//	/SAG output disabled when set (default)
#define	MR_MODE_ASUSPEND		0x0010	//	Suspend (sleep) ADCs when set
#define	MR_MODE_TEMPSEL			0x0020	//	Start a temperature conversion when set ("ADCSC")
#define	MR_MODE_SWRST			0x0040	//	Software Chip Reset
#define	MR_MODE_CYCMODE			0x0080	//	Line Cycle Energy Accumulation Mode
#define	MR_MODE_DISCH1			0x0100	//	Short analog inputs, current channel
#define	MR_MODE_DISCH2			0x0200	//	Short analog inputs, voltage channel
#define	MR_MODE_SWAP			0x0400	//	Swap voltage & current channels
#define	MR_MODE_DTRT_28K		0x0000	//	Default: 27.9ksps (CLKIN/128)
#define	MR_MODE_DTRT_14K		0x0800	//
#define	MR_MODE_DTRT_7K			0x1000	//
#define	MR_MODE_DTRT_3K			0x1800	//
#define	MR_MODE_WAVSEL_ACTIVE	0x0000	//  Waveform select
#define	MR_MODE_WAVSEL_CH1		0x4000	//
#define	MR_MODE_WAVSEL_CH2		0x6000	//
#define	MR_MODE_POAM			0x8000	//	Positive-power Only Accumulation Mode

//
// STATUS (& RSTATUS & IRQEN) register bits
//
//	(also used to set the interrupt MASK register.
//		For the MASK, set the bit if an IRQ should be generated for
//		the corresponding event.  Only _RESET does not apply.)
//
#define	MR_STATUS_AEHF		0x0001	// AENERGY accumulator is half-full
#define	MR_STATUS_SAG		0x0002	// Voltage sag below threshold
#define	MR_STATUS_CYCEND	0x0004  // End of LINECYC half-line cycles
#define	MR_STATUS_WSMP		0x0008	// Waveform samples data ready
#define	MR_STATUS_ZX		0x0010	// Zero crossing occurred (also ZX output)
#define	MR_STATUS_TEMP		0x0020	// Temperature data ready
#define	MR_STATUS_RESET		0x0040	// End of software/hardware reset
#define	MR_STATUS_AEOF		0x0080	// AENERGY accumulator has overflowed
#define	MR_STATUS_PKV		0x0100	// Peak voltage has been exceeded
#define	MR_STATUS_PKI		0x0200	// Peak current has been exceeded
#define	MR_STATUS_VAEHF		0x0400	// VAENERGY accumulator is half full
#define	MR_STATUS_VAEOF		0x0800	// VAENERGY accumulator has overflowed
#define	MR_STATUS_ZXTO		0x1000  // Zero crossing time-out occurred
#define	MR_STATUS_PPOS		0x2000	// Power negative to positive
#define	MR_STATUS_PNEG		0x4000	// Power positive to negative
#define	MR_STATUS_UNUSED	0x8000	// Reserved bit

A note from rev history.  This app uses AENERGY and VAENERGY to do controlling based on power factor -- an oversized idling motor might draw say 2 amps, but when actually working still draw about 2 amps.  But the power factor will change...

 

 *				b	Add ADE7763 commo
 *						Basic function of init, 1-second capture of AENERGY & VAENERGY,
 *							and capture of VRMS & IRMS right after zero crossing.
 *							No cal or units.
 *						Works quite well.  VRMS is steady at about 2500 "counts" (   VAC)
 						IRMS at ~6700 for 4.2A idle load; VAENERGY tracks the IRMS.
 						AENERGY is ~-925 counts at idle.
 						~4.5A load shows 5% rise in IRMS and VAENERGY, but AENERGY goes to ~+800.

 						~6A load, IRMS & VAENERGY increas about 50% as expected.
 						AENERGY goes from -600 to ~+5000.

 *				c 	Replace VRMS with counts from the CF input.

Driver prototypes

	// ADE7763 Energy Meter -- SPI
unsigned char				meter_read			(unsigned char addr, unsigned char * data, unsigned char count);
unsigned char				meter_dump			(unsigned char addr, unsigned char * data);
unsigned char				meter_write			(unsigned char addr, unsigned char * data, unsigned char count);
unsigned char				meter_init			(void);
unsigned char				meter_put			(unsigned char eeprom * config);

Oh, yeah--this app is in CodeVision.  EEPROM array of register type/width, and EEPROM struct of initial values:

 

//
//	ADE7763 Register Use Parameters
//	===============================
//
//	There is one byte in this table for each of the 64 registers
//	in the ADE7763.  Each register can be read-only, read-write, write-only,
//	or neither (such as the unused "reserved" registers).  There are also
//	registers which clear internal accumulators when read.  The access bits are
//	from a remote program (like the PC) point of view.
//
//	Also, the data lengths for each item are different, ranging from 6 bits to
//	24.   Since the SPI interface to the '7763 uses whole bytes, the communication
//	byte length is encoded.
//
//	Bit 7:		If 1, read allowed
//	Bit 6:		If 1, write allowed
//	Bits 1&0:	Commo byte width, 0-3
//	Bit 2:	    Reserved
//	Bits 5-4-3:	Storage width, typically 1, 2, or 4 to match C data types
//
#define		MR_READ_OK		0x80
#define		MR_WRITE_OK		0x40
#define		MR_READ_WRITE	(MR_READ_OK | MR_WRITE_OK)
#define		MR_NO_ACCESS	0x00

#define		MR_SPI_0		0x00
#define		MR_SPI_1		0x01
#define		MR_SPI_2		0x02
#define		MR_SPI_3		0x03

#define		MR_BYTE_0		0x00
#define		MR_BYTE_1		0x04
#define		MR_BYTE_2		0x10
#define		MR_BYTE_4		0x20

eeprom	unsigned char	ee_reg_7763 [64] =
{
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	00h Reserved
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	01h WFORM		R	24	0	Waveform
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	02h AENERGY		R	24	0	Active Energy
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	03h RAENERGY	R	24	0	AENERGY with reset
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	04h LAENERGY	R	24	0	Line Accumulation Active Energy
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	05h VAENERGY	R	24	0	VA Energy
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	06h RVAENERGY	R	24	0	VAENERGY with reset
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	07h LVAENERGY	R	24	0	Real Energy
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	08h Reserved
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	09h MODE		R/W	16	0Ch	Operational Mode
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	0Ah IRQEN		R/W	16	40h	IRQ Mask
MR_READ_OK | MR_BYTE_2 | MR_SPI_2,				//	0Bh STATUS		R	16	0	IRQ Status
MR_READ_OK | MR_BYTE_2 | MR_SPI_2,				//	0Ch RSTATUS		R	16	0	STATUS with reset
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	0Dh CH1OS		R/W	8	0	Current channel offset adjust
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	0Eh CH2OS		R/W	8	0	Voltage channel offset adjust
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	0Fh GAIN		R/W	8	0	PGA Gain
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	10h PHCAL		R/W	6	0	Phase Calibration
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	11h APOS		R/W	16	0	Active Power Offset Calibration
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	12h WGAIN		R/W	12	0	Active Power Gain Adjust
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	13h WDIV		R/W	8	0	Active Energy  divider
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	14h CFNUM		R/W	12	3Fh	CF Scaling Numerator
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	15h CFDEN		R/W	12	3Fh	CF Scaling Denominator
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	16h IRMS		R	24	0	Current channel RMS
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	17h VRMS		R	24	0	Voltage channel RMS
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	18h IRMSOS		R/W	12	0	Current RMS offset correction
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	19h VRMSOS		R/W	12	0	Voltage RMS offset correction
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	1Ah VAGAIN		R/W	12	0	Apparent Power Gain Adjust
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	1Bh VADIV		R/W	8	0	Apparent Energy  divider
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	1Ch LINECYC		R/W	16	FFFFh	Line Cycle
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	1Dh ZXTOUT		R/W	12	FFFh	Zero Cross Time Out
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	1Eh SAGCYC		R/W	8	FFh		Sag Line Cycle
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	1Fh SAGLVL		R/W	8	0		SAG Voltage Level
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	20h IPKLVL		R/W	8	FFh		Current Peak Level--ALARM
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	21h VPKLVL		R/W	8	FFh		Voltage Peak Level--ALARM
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	22h IPEAK		R	24	0	Current Peak Register
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	23h RSTIPEAK	R	24	0	Current Peak Register with Reset
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	24h VPEAK		R	24	0	Voltage Peak Register
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	25h RSTVPEAK	R	24	0	Voltage Peak Register with Reset
MR_READ_OK | MR_BYTE_1 | MR_SPI_1,				//	26h TEMP		R	8	0	Temperature
MR_READ_OK | MR_BYTE_2 | MR_SPI_2,				//	27h PERIOD		R	15	0	Period of the line input
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	28h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	29h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	2Ah Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	2Bh Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	2Ch Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	2Dh Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	2Eh Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	2Fh Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	30h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	31h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	32h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	33h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	34h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	35h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	36h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	37h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	38h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	39h Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	3Ah Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	3Bh Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	3Ch Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	3Dh Reserved
MR_READ_OK | MR_BYTE_1 | MR_SPI_1,				//	3Eh CHKSUM		R	8	0	Check sum (6 bits)
MR_READ_OK | MR_BYTE_1 | MR_SPI_1				//	3Fh DIEREV		R	8	0	Version of the Die
};

//
// **************************************************************************
// *	A D E 7 7 5 4   R E G I S T E R S   &   O T H E R   C O N F I G
// **************************************************************************
//
//	These structures contain primary and secondary configurations items
//	to be loaded at cold startup (power-on).
//
//	A to-be-defined checksum and validity flag will be used to decide
//	which copy, if any, to pass to the '7763.
//
eeprom struct	config_7763
{
/*
 *	This structure is laid out in register order, according to ee_reg_7763
 *	declared above.  Each item in ee_reg_7763 that can be written (MR_READ_WRITE)
 *	has an entry into this structure.  When loading/dumping configuration to the
 *	'7763, the offset into the structure can be obtained by processing from the
 *	top of ee_reg_7763 and calculating the offset by summing the MR_BYTE_* bits
 *	up to the desired field.
 *
 *	The alternatives would be to address the fields by name, or to have yet
 *	another table, 64 bytes long, with the offset.
 */
unsigned int		mode        ;			//	09h MODE
unsigned int		irqen       ;			//	0Ah IRQEN
unsigned char		gain        ;			//	0Fh GAIN
unsigned char		phcal       ;			//	10h PHCAL
unsigned int		apos        ;			//	11h APOS
unsigned int		wgain       ;			//	12h WGAIN
unsigned char		wdiv        ;			//	13h WDIV
unsigned int		cfnum       ;			//	14h CFNUM
unsigned int		cfden       ;			//	15h CFDEN
unsigned int		irmsos      ;			//	18h IRMSOS
unsigned int		vrmsos      ;			//	19h VRMSOS
unsigned int		vagain      ;			//	1Ah VAGAIN
unsigned char		vadiv       ;			//	1Bh VADIV
unsigned int		linecyc     ;			//	1Ch LINECYC
unsigned int		zxtout      ;			//	1Dh ZXTOUT
unsigned char		sagcyc      ;			//	1Eh SAGCYC
unsigned char		saglvl      ;			//	1Fh SAGLVL
unsigned char		ipeaklvl    ;			//	20h IPEAK
unsigned char		vpeaklvl    ;			//	21h VPKLVL
};


eeprom	struct config_7763		ee_meter = {
														// meter configuration registers:
0x0c,		//  09h MODE
0x40,		//  0Ah IRQEN
0,		//  0Fh GAIN
0,		//  10h PHCAL
0,		//  11h APOS
0,		//  12h WGAIN
0,		//  13h WDIV
0,		//  14h CFNUM
0,		//  15h CFDEN
0,		//  18h IRMSOS
0,		//  19h VRMSOS
0,		//  1Ah VAGAIN
0,		//  1Bh VADIV
0xffff,		//  1Ch LINECY
0xfff,		//  1Dh ZXTOUT
0xff,		//  1Eh SAGCYC
0,			//  1Fh SAGLVL
0xff,		//  20h IPEAK
0xff		//  21h VPKLVL
};

The "driver":

//
// **************************************************************************
// *
// *	A D E 7 7 6 3   E N E R G Y   M E T E R   C H I P   D R I V E R
// *
// **************************************************************************
//
//	These routines carry out the common functions of SPI serial
//	interaction with an Analog Devices ADE7763 Energy Meter chip.
//	Read, Write, and Init functions have been identified.
//
// **************************************************************************
// *	M E T E R _ R E A D
// **************************************************************************
//
unsigned char				meter_read			(unsigned char addr,
												unsigned char * data,
												unsigned char count)
{
unsigned char i;	// working variable

	SELECT_7763 = 0;						// select '7763 energy meter
#asm("cli");

	spi(addr);								// send op code
											// (which is register number in low 6 bits)
	for (i=0; i<count; i++)
		{
		*data-- = spi (0x00);				// read all the bytes and store
		}

#asm("sei");
	SELECT_7763 = 1;						// de-select '7763 energy meter
	return (1);								// success
}
// **************************************************************************
// *	M E T E R _ D U M P
// **************************************************************************
//
//	"addr" is an ADE7763 register number.  Output the value up to 2 bytes
//	in Modbus MSByte-first order to the character pointer.  Use the
//	ee_reg_7763 array to figure out how wide the register is.
//
unsigned char				meter_dump			(unsigned char addr,
												unsigned char * data)
{
unsigned char i;		// working variable

		i = ee_reg_7763[addr];
		if (i & MR_READ_OK)
			{
							// Mask off the length bits.
							// These registers all have MR_SPI_* == MR_BYTE_*.
			i &= 0x03;

			SELECT_7763 = 0;				// select '7763 energy meter
			#asm("cli");

			spi(addr);						// send op code
											// (which is register number in low 6 bits)
			if (i == 1)
				{
							// 8-bit register; one byte transfer & store
				*data++ = 0;	// null byte
				*data++ = spi (0x00);	// read the data byte and store
				}
			else
				{
							// 16-bit register; two byte transfer & store.
							//	MSB first.  If 24-bit, get the high 16 bits.
				*data++ = spi (0x00);	// read the data byte and store
				*data++ = spi (0x00);	// read the data byte and store
				}

			#asm("sei");
			SELECT_7763 = 1;						// de-select '7763 energy meter
			return (1);								// success
			}
		else
			{
			*data++ = 0;	// null byte
			*data++ = 0;	// null byte
			return (0);		// failure
			}

}
//
// **************************************************************************
// *	M E T E R _ W R I T E
// **************************************************************************
//
unsigned char				meter_write			(unsigned char addr,
												unsigned char * data,
												unsigned char count)
{
unsigned char i;	// working variable

	SELECT_7763 = 0;						// select '7763 energy meter
#asm("cli");
	spi(addr | 0x80);						// send op code
											// (which is register number in low 6 bits,
											//	plus high bit set indicating a write)
	for (i=0; i<count; i++)
		{
		spi(*data--);						// write all the bytes
		}
#asm("sei");

	SELECT_7763 = 1;						// de-select '7763 energy meter
	return (1);								// success
}
//
// **************************************************************************
// *	M E T E R _ I N I T
// **************************************************************************
//
//	Call for a software reset of the chip, per Rev. E errata.
//	Read back the chip revision number and return it,
//		as a kind of check that the chip is alive.
//
unsigned char				meter_init			(void)
{
static unsigned char	i;	// working variable
static unsigned int	j;	// working variable

	j = MR_MODE_SWRST;		// MODE register, SWRST bit;
//	j = 0x8485;		// MODE register, SWRST bit;
	meter_write (MR_MODE, (unsigned char *)&j, 2);		// MODE register, SWRST bit
	delay_ms (2);						// data sheet calls for 18us for sw reset
                 // [50us seems to be too short; 1ms seems to be plenty]
	meter_read (MR_RSTATUS,(unsigned char *) &j, 2);		// Read/clear STATUS after SWRST

	meter_read (MR_VERSION, &i, 1);		// VERSION register, 8 bits [expect 0x81]
	return (i);							// VERSION register contents to caller
}
//
// **************************************************************************
// *	M E T E R _ P U T
// **************************************************************************
//
//	Output a set of configuration registers to the ADE7763 Energy Meter chip.
//
//	Typically, this will be done at pwoer-on, since the chip is volatile.
//
//	Use the flags in the ee_reg_7763 array to write each writable register,
//	using the values contained in the given config_7763 structure.
//
//	Start at a 0 offset and first register.  For each register that is MR_WRITE_OK,
//		put the correct number of bytes from the given structure to the chip.
//
//	Note that the structure pointer is passed as a character pointer, since
//	only the offset and length will be used, not the field names.
//
unsigned char				meter_put			(unsigned char eeprom * config)
{
unsigned char	i;		// working variable
unsigned char	reg;	// register number
unsigned char	data1;	// one-byte data holder
unsigned int	data2;	// two-byte data holder
unsigned char	*addr;	// working address

	for (reg=0; reg < 64; reg++)
		{
		i = ee_reg_7763[reg];
		if (i & MR_WRITE_OK)
			{
							// Mask off the length bits.
							// These registers all have MR_SPI_* == MR_BYTE_*.
			i &= 0x03;
			if (i == 1)
				{
							// 8-bit register; one byte transfer & store
				data1 = *config;	// get the byte
				meter_write (reg, &data1, i);
				config++;
				}
			else
				{
							// 16-bit register; two byte transfer & store
				data2 = *((unsigned int eeprom*)config);
														// point to most significant byte
//				addr = &(unsigned char)data2 + 1;
				addr = (unsigned char*)&data2 + 1;
			  //	addr++;
				meter_write (reg, addr, i);	// and output the value
				config += 2;	// adjust the offset
				}
			}
		}

	return (1);				// Default success--no error checking each step
}

A few variables and such:

// **************************************************************************
//	32-bit value union for remapping/"generic" data
// **************************************************************************
union	longmap
{
unsigned long int		u32;			// 32-bit mapping
unsigned int			u16[2];			// 16-bit mapping
unsigned char			u8[4];			// 8-bit mapping
};
...
unsigned int			signal_vrms;	// RMS voltage
unsigned int			signal_irms;	// RMS current
unsigned int			aenergy;		// High 16 bits of LAENERGY
unsigned int			vaenergy;		// High 16 bits of LVAENERGY

union	longmap			msg_param;		// and yet another way to break up a 32-bit value
union	longmap			msg_isr;		// and yet another way to break up a 32-bit value

A few usage examples:

		if ((ticks == 31) && tack) // once a second
			{
// Active (Real) Energy
			meter_read (MR_RAENERGY, &msg_param.u8[2], 3);
			aenergy = msg_param.u16[0];		// low 16 bits -- won't overflow in 1 second
			}

		if ((ticks == 41) && tack) // once a second
			{
// Apparent (VA) Energy
			meter_read (MR_RVAENERGY, &msg_param.u8[2], 3);		// -- use low 16 bits.
			vaenergy = msg_param.u16[0];		// low 16 bits -- won't overflow in 1 second
			}
...
(how it might be used -- my real app was different)
//
//	Gather power numbers every second-- real (active) and apparent.
//
//
// Active (Real) Energy
			meter_read (MR_RAENERGY, &msg_param.u8[2], 3);
			aenergy = msg_param.u16[0];		// low 16 bits -- won't overflow in 1 second
			if (aenergy > 60000)
				{
				// probably a small negative number
				aenergy = 0;
				}
			// Convert watt-hours into kilowatts for this one second sample
			user_data[UD_REAL] = conv_int_disp( (int)aenergy, SIGNAL_KW);

// Apparent (VA) Energy
			meter_read (MR_RVAENERGY, &msg_param.u8[2], 3);
			// -- use low 16 bits.
			// -- convert to watt-hours by multiplying by 3.657
			vaenergy = (unsigned int) calcc (msg_param.u16[0],	// low 16 bits -- won't overflow in 1 second
							3657, 1000, 0);
			if (vaenergy > 60000)
				{
				// probably a small negative number
				vaenergy = 0;
				}
			// Convert watt-hours into kilowatts for this one second sample
			user_data[UD_APPARENT] = conv_int_disp( (int)vaenergy, SIGNAL_KW);

// Power Factor (only calculate if meaningful)
			if (i_ave > cutoff_current)
				{
//				user_data[UD_PF] = calcy( (int)aenergy, 100, (int)vaenergy, 0);
				user_data[UD_PF] = (unsigned long)aenergy * 100l / (unsigned long)vaenergy;

				}
			else
				{
				user_data[UD_PF] = 0;
				}

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The above '7763 was from 2007.  Below '7754 from 2002.  So I'm rusty.  Some corresponding fragments to the above; 3-phase device shown in the link earlier.

 

reg7754.h

//
//	Analog Devices ADE7754 Energy Meter Chip
//	****************************************
//
//	MR_ = Meter Register
//
//	In general, names and abbreviations are as used in ADE7754 data sheet, Rev. E
//

//
//	Register Address Definitions
//
#define	MR_Reserv00		0x00
#define	MR_AENERGY      0x01
#define	MR_RAENERGY     0x02
#define	MR_LAENERGY     0x03
#define	MR_VAENERGY     0x04
#define	MR_RVAENERGY    0x05
#define	MR_LVAENERGY    0x06
#define	MR_PERIOD       0x07
#define	MR_TEMP         0x08
#define	MR_WFORM        0x09
#define	MR_OPMODE       0x0A
#define	MR_MMODE        0x0B
#define	MR_WAVMODE      0x0C
#define	MR_WATMODE      0x0D
#define	MR_VAMODE       0x0E
#define	MR_MASK         0x0F
#define	MR_STATUS       0x10
#define	MR_RSTATUS      0x11
#define	MR_ZXTOUT       0x12
#define	MR_LINCYC       0x13
#define	MR_SAGCYC       0x14
#define	MR_SAGLVL       0x15
#define	MR_VPEAK        0x16
#define	MR_IPEAK        0x17
#define	MR_GAIN         0x18
#define	MR_AWG          0x19
#define	MR_BWG          0x1A
#define	MR_CWG          0x1B
#define	MR_AVAG         0x1C
#define	MR_BVAG         0x1D
#define	MR_CVAG         0x1E
#define	MR_APHCAL       0x1F
#define	MR_BPHCAL       0x20
#define	MR_CPHCAL       0x21
#define	MR_AAPOS        0x22
#define	MR_BAPOS        0x23
#define	MR_CAPOS        0x24
#define	MR_CFNUM        0x25
#define	MR_CFDEN        0x26
#define	MR_WDIV         0x27
#define	MR_VADIV        0x28
#define	MR_AIRMS        0x29
#define	MR_BIRMS        0x2A
#define	MR_CIRMS        0x2B
#define	MR_AVRMS        0x2C
#define	MR_BVRMS        0x2D
#define	MR_CVRMS        0x2E
#define	MR_AIRMSOS      0x2F
#define	MR_BIRMSOS      0x30
#define	MR_CIRMSOS      0x31
#define	MR_AVRMSOS      0x32
#define	MR_BVRMSOS      0x33
#define	MR_CVRMSOS      0x34
#define	MR_AAPGAIN      0x35
#define	MR_BAPGAIN      0x36
#define	MR_CAPGAIN      0x37
#define	MR_AVGAIN       0x38
#define	MR_BVGAIN       0x39
#define	MR_CVGAIN       0x3A
#define	MR_Reserv3B     0x3B
#define	MR_Reserv3C     0x3C
#define	MR_Reserv3D     0x3D
#define	MR_CHKSUM       0x3E
#define	MR_VERSION      0x3F

//
// STATUS (& RSTATUS) register bits
//
//	(also used to set the interrupt MASK register.
//		For the MASK, set the bit if an IRQ should be generated for
//		the corresponding event.  Only _RESET does not apply.)
//
#define	MR_STATUS_AEHF		0x0001	// AENERGY accumulator is half-full
#define	MR_STATUS_SAGA		0x0002	// Phase A voltage sag below threshold
#define	MR_STATUS_SAGB		0x0004  // Phase B voltage sag below threshold
#define	MR_STATUS_SAGC		0x0008	// Phase C voltage sag below threshold
#define	MR_STATUS_ZXTOA		0x0010	// Zero crossing time-out occurred, phase A
#define	MR_STATUS_ZXTOB		0x0020  // Zero crossing time-out occurred, phase B
#define	MR_STATUS_ZXTOC		0x0040	// Zero crossing time-out occurred, phase C
#define	MR_STATUS_ZXA		0x0080	// Zero crossing occurred, phase A
#define	MR_STATUS_ZXB		0x0100	// Zero crossing occurred, phase B
#define	MR_STATUS_ZXC		0x0200	// Zero crossing occurred, phase C
#define	MR_STATUS_LENERGY	0x0400	// End of integration over LINCYC line cycles
#define	MR_STATUS_RESET		0x0800	// 5v power supply is below 4v
#define	MR_STATUS_PKV		0x1000	// Peak voltage on selected phase has been exceeded
#define	MR_STATUS_PKI		0x2000	// Peak current on selected phase has been exceeded
#define	MR_STATUS_WFSM		0x4000	// Waveform register data is available to be read
#define	MR_STATUS_VAEHF		0x8000	// VAENERGY accumulator is half full

//
//	OPMODE register bits
//
//	There are valid combinations of the SWAP and A/D disable functions,
//	which would not be used during normal operation.
//
//	ADE7754 default at power-up:  0x04 ==>  Normal + DISCF
//
#define	MR_OPMODE_NORMAL	0b00000000	//	Normal operation
#define	MR_OPMODE_DISHPF	0b00000001	//	High-pass filters disabled when set
#define	MR_OPMODE_DISLPF	0b00000010	//	Low-pass filters disabled when set
#define	MR_OPMODE_DISCF		0b00000100	//	CF output disabled when set
#define	MR_OPMODE_SWAP		0b00100000	//	Current & voltage A/D channels swapped when set
#define	MR_OPMODE_DISCUR	0b00001000	//	Current A/D disabled when set
#define	MR_OPMODE_DISVOLT	0b00010000	//	Voltage A/D disabled when set
#define	MR_OPMODE_SLEEP		0b00011000	//	ADE7754 sleep mode whan set
#define	MR_OPMODE_POWDOWN	0b00111000	//	ADE7754 powered down when set
#define	MR_OPMODE_SWRST		0b01000000	//	Software reset when set [automatic reset??]

//
//	MMODE register bits
//
//	bits 0-1:	PERDSEL	Period select	00 -- phase A; 01 -- phase B; 10 -- phase C
//	bits 2-3:	PEAKSEL	Peak select		00 -- phase A; 01 -- phase B; 10 -- phase C
//	bits 4-6:	ZXSEL	Zero Crossing select Phase A-B-C is bits 4-5 6
//
#define	MR_MMODE_PERD_A		0b00000000	//  Period select -- phase A
#define	MR_MMODE_PERD_B		0b00000001	//	Period select -- phase B
#define	MR_MMODE_PERD_C		0b00000010	//	Period select -- phase C
#define	MR_MMODE_PEAK_A		0b00000000	//	Peak select -- phase A
#define	MR_MMODE_PEAK_B		0b00000100	//	Peak select -- phase B
#define	MR_MMODE_PEAK_C		0b00001000	//	Peak select -- phase C
#define	MR_MMODE_ZX_A		0b00010000	//	ZX select -- phase A
#define	MR_MMODE_ZX_B		0b00100000	//	ZX select -- phase B
#define	MR_MMODE_ZX_C		0b01000000	//	ZX select -- phase C

#define	MR_MMODE_MASK_PERD	0b00000011	//	Mask for manipulating Period bits
#define	MR_MMODE_MASK_PEAK	0b00001100	//	Mask for manipulating Peak Select bits
#define	MR_MMODE_MASK_ZX	0b01110000	//	Mask for manipulating Zero Crossing bits

 

Driver prototypes

	// ADE7754 Energy Meter -- SPI
unsigned char				meter_read			(unsigned char addr, unsigned char * data, unsigned char count);
unsigned char				meter_dump			(unsigned char addr, unsigned char * data);
unsigned char				meter_write			(unsigned char addr, unsigned char * data, unsigned char count);
unsigned char				meter_init			(void);
unsigned char				meter_put			(unsigned char eeprom *config);

EEPROM stuff

 

//
//	ADE7754 Register Use Parameters
//	===============================
//
//	There is one byte in this table for each of the 64 registers
//	in the ADE7754.  Each register can be read-only, read-write, write-only,
//	or neither (such as the unused "reserved" registers).  There are also
//	registers which clear internal accumulators when read.  The access bits are
//	from a remote program (like the PC) point of view.
//
//	Also, the data lengths for each item are different, ranging from 6 bits to
//	24.   Since the SPI interface to the '7754 uses whole bytes, the communication
//	byte length is encoded.
//
//	Bit 7:		If 1, read allowed
//	Bit 6:		If 1, write allowed
//	Bits 1&0:	Commo byte width, 0-3
//	Bit 2:	    Reserved
//	Bits 5-4-3:	Storage width, typically 1, 2, or 4 to match C data types
//
#define		MR_READ_OK		0x80
#define		MR_WRITE_OK		0x40
#define		MR_READ_WRITE	(MR_READ_OK | MR_WRITE_OK)
#define		MR_NO_ACCESS	0x00

#define		MR_SPI_0		0x00
#define		MR_SPI_1		0x01
#define		MR_SPI_2		0x02
#define		MR_SPI_3		0x03

#define		MR_BYTE_0		0x00
#define		MR_BYTE_1		0x04
#define		MR_BYTE_2		0x10
#define		MR_BYTE_4		0x20

eeprom	unsigned char	ee_reg_7754 [64] =
{
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	00h Reserved
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	01h AENERGY	R	24	0	Active Energy
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	02h RAENERGY	R	24	0	AENERGY with reset
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	03h LAENERGY	R	24	0	Line Accumulation Active Energy
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	04h VAENERGY	R	24	0	VA Energy
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	05h RVAENERGY	R	24	0	VAENERGY with reset
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	06h LVAENERGY	R	24	0	Real Energy
MR_READ_OK | MR_BYTE_2 | MR_SPI_2,				//	07h PERIOD	R	15	0	Period of the line input
MR_READ_OK | MR_BYTE_1 | MR_SPI_1,				//	08h TEMP	R	8	0	Temperature
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	09h WFORM	R	24	0	Waveform
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	0Ah OPMODE	R/W	 8	4	Operational Mode
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	0Bh MMODE	R/W	 8	70h	Measurement Mode
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	0Ch WAVMODE	R/W	 8	0	Waveform Mode
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	0Dh WATMODE	R/W	 8	3Fh	Active Energy Formula
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	0Eh VAMODE	R/W	 8	3Fh	Apparent Energy Formula
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	0Fh MASK	R/W	 16	0	IRQ Mask
MR_READ_OK | MR_BYTE_2 | MR_SPI_2,				//	10h STATUS	R	16	0	IRQ Status
MR_READ_OK | MR_BYTE_2 | MR_SPI_2,				//	11h RSTATUS	R	16	0	STATUS with reset
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	12h ZXTOUT	R/W	 16	FFFFh	Zero Cross Time Out
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	13h LINCYC	R/W	 16	FFFFh	Line Cycle
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	14h SAGCYC	R/W	 8	FFh	Sag Line Cycle
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	15h SAGLVL	R/W	 8	0	SAG Voltage Level
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	16h VPEAK	R/W	 8	FFh	Voltage Peak Level
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	17h IPEAK	R/W	 8	FFh	Current Peak Level
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	18h GAIN	R/W	 8	0	PGA Gain
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	19h AWG		R/W	 12	0	Phase A Active Power Gain
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	1Ah BWG		R/W	 12	0	Phase B Active Power Gain
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	1Bh CWG		R/W	 12	0	Phase C Active Power Gain
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	1Ch AVAG	R/W	 12	0	VA Gain
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	1Dh BVAG	R/W	 12	0	Phase B VA Gain
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	1Eh CVAG	R/W	 12	0	Phase C VA Gain
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	1Fh APHCAL	R/W	 6	0	Phase A Phase Calibration
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	20h BPHCAL	R/W	 6	0	Phase B Phase Calibration
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	21h CPHCAL	R/W	 6	0	Phase C Phase Calibration
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	22h AAPOS	R/W	 12	0	Phase A Power Offset Calibration
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	23h BAPOS	R/W	 12	0	Phase B Power Offset Calibration
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	24h CAPOS	R/W	 12	0	Phase C Power Offset Calibration
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	25h CFNUM	R/W	 12	3Fh	CF Scaling Numerator
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	26h CFDEN	R/W	 12	3Fh	CF Scaling Denominator
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	27h WDIV	R/W	 8	0	Active Energy  divider
MR_READ_WRITE | MR_BYTE_1 | MR_SPI_1,			//	28h VADIV	R/W	 8	0	Apparent Energy  divider
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	29h AIRMS	R	24	0	Phase A Current channel RMS
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	2Ah BIRMS	R	24	0	Phase B Current channel RMS
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	2Bh CIRMS	R	24	0	Phase C Current channel RMS
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	2Ch AVRMS	R	24	0	Phase A Voltage channel RMS
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	2Dh BVRMS	R	24	0	Phase B Voltage channel RMS
MR_READ_OK | MR_BYTE_4 | MR_SPI_3,				//	2Eh CVRMS	R	24	0	Phase C Voltage channel RMS
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	2Fh AIRMSOS	R/W	 12	0	Phase A Current RMS offset correction
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	30h BIRMSOS	R/W	 12	0	Phase B Current RMS offset correction
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	31h CIRMSOS	R/W	 12	0	Phase C Current RMS offset correction
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	32h AVRMSOS	R/W	 12	0	Phase A Voltage RMS offset correction
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	33h BVRMSOS	R/W	 12	0	Phase B Voltage RMS offset correction
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	34h CVRMSOS	R/W	 12	0	Phase C Voltage RMS offset correction
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	35h AAPGAIN	R/W	 12	0	Phase A Active Power Gain Adjust
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	36h BAPGAIN	R/W	 12	0	Phase B Active Power Gain Adjust
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	37h CAPGAIN	R/W	 12	0	Phase C Active Power Gain Adjust
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	38h AVGAIN	R/W	 12	0	Phase A voltage RMS gain
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	39h BVGAIN	R/W	 12	0	Phase B voltage RMS gain
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	3Ah CVGAIN	R/W	 12	0	Phase C voltage RMS gain
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	3Bh Reserved
MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	3Ch Reserved
//MR_NO_ACCESS | MR_BYTE_0 | MR_SPI_0,			//	3Dh Reserved
MR_READ_WRITE | MR_BYTE_2 | MR_SPI_2,			//	3Dh Reserved -- special current channel cal.
MR_READ_OK | MR_BYTE_1 | MR_SPI_1,				//	3Eh CHKSUM	R	8	0	Check sum
MR_READ_OK | MR_BYTE_1 | MR_SPI_1				//	3Fh VERSION	R	8	0	Version of the Die
};

//
// **************************************************************************
// *	A D E 7 7 5 4   R E G I S T E R S   &   O T H E R   C O N F I G
// **************************************************************************
//
//	These structures contain primary and secondary configurations items
//	to be loaded at cold startup (power-on).
//
//	A to-be-defined checksum and validity flag will be used to decide
//	which copy, if any, to pass to the '7754.
//
eeprom struct	config_7754
{
/*
 *	This structure is laid out in register order, according to ee_reg_7754
 *	declared above.  Each item in ee_reg_7754 that can be written (MR_READ_WRITE)
 *	has an entry into this structure.  When loading/dumping configuration to the
 *	'7754, the offset into the structure can be obtained by processing from the
 *	top of ee_reg_7754 and calculating the offset by summing the MR_BYTE_* bits
 *	up to the desired field.
 *
 *	The alternatives would be to address the fields by name, or to have yet
 *	another table, 64 bytes long, with the offset.
 */
unsigned char		opmode      ;			//	0Ah OPMODE
unsigned char		mmode       ;			//	0Bh MMODE
unsigned char		wavmode     ;			//	0Ch WAVMODE
unsigned char		watmode     ;			//	0Dh WATMODE
unsigned char		vamode      ;			//	0Eh VAMODE
unsigned int		mask        ;			//	0Fh MASK
unsigned int		zxtout      ;			//	12h ZXTOUT
unsigned int		lincyc      ;			//	13h LINCYC
unsigned char		sagcyc      ;			//	14h SAGCYC
unsigned char		saglvl      ;			//	15h SAGLVL
unsigned char		vpeak       ;			//	16h VPEAK
unsigned char		ipeak       ;			//	17h IPEAK
unsigned char		gain        ;			//	18h GAIN
unsigned int		awg         ;			//	19h AWG
unsigned int		bwg         ;			//	1Ah BWG
unsigned int		cwg         ;			//	1Bh CWG
unsigned int		avag        ;			//	1Ch AVAG
unsigned int		bvag        ;			//	1Dh BVAG
unsigned int		cvag        ;			//	1Eh CVAG
unsigned char		aphcal      ;			//	1Fh APHCAL
unsigned char		bphcal      ;			//	20h BPHCAL
unsigned char		cphcal      ;			//	21h CPHCAL
unsigned int		aapos       ;			//	22h AAPOS
unsigned int		bapos       ;			//	23h BAPOS
unsigned int		capos       ;			//	24h CAPOS
unsigned int		cfnum       ;			//	25h CFNUM
unsigned int		cfden       ;			//	26h CFDEN
unsigned char		wdiv        ;			//	27h WDIV
unsigned char		vadiv       ;			//	28h VADIV
unsigned int		airmsos     ;			//	2Fh AIRMSOS
unsigned int		birmsos     ;			//	30h BIRMSOS
unsigned int		cirmsos     ;			//	31h CIRMSOS
unsigned int		avrmsos     ;			//	32h AVRMSOS
unsigned int		bvrmsos     ;			//	33h BVRMSOS
unsigned int		cvrmsos     ;			//	34h CVRMSOS
unsigned int		aapgain     ;			//	35h AAPGAIN
unsigned int		bapgain     ;			//	36h BAPGAIN
unsigned int		capgain     ;			//	37h CAPGAIN
unsigned int		avgain      ;			//	38h AVGAIN
unsigned int		bvgain      ;			//	39h BVGAIN
unsigned int		cvgain      ;			//	3Ah CVGAIN
unsigned int		reserv3d	;			//  3Dh Special current channel cross-talk
};


eeprom	struct config_7754		ee_meter = {
														// meter configuration registers:
//			0, 0x70, 0, 0x35, 0x35, 0,	// 0x0a-0x0f
			0, 0x70, 0, 0x36, 0x3f, 0,	// 0x0a-0x0f updated for 6-6 & 7-7 in
										//	WATSEL-LWATSEL & VASEL-LVASEL 6 JUN 03 per Bill R.
			0xffff, 0xffff, 0xff, 0, 0xff, 0xff, //0x12-0x17
			0, 0, 0, 0, 0, 0, 0, 	// 0x18-0x1e
			0, 0, 0, 0, 0, 0,		// 0x1f-0x24
			0x3f, 0x3f, 1, 1,		// 0x25-0x28
            0, 0, 0, 0, 0, 0,		// 0x2f-0x34
            0, 0, 0, 0, 0, 0,		// 0x35-0x3a
            0x01f7					// 0x3d

};

Driver

 

//
// **************************************************************************
// *
// *	A D E 7 7 5 4   E N E R G Y   M E T E R   C H I P   D R I V E R
// *
// **************************************************************************
//
//	These routines carry out the common functions of SPI serial
//	interaction with an Analog Devices ADE7754 Energy Meter chip.
//	Read, Write, and Init functions have been identified.
//
// **************************************************************************
// *	M E T E R _ R E A D
// **************************************************************************
//
unsigned char				meter_read			(unsigned char addr,
												unsigned char * data,
												unsigned char count)
{
unsigned char i;	// working variable

	SELECT_7754 = 0;						// select '7754 energy meter
#asm("cli");

	spi(addr);								// send op code
											// (which is register number in low 6 bits)
	for (i=0; i<count; i++)
		{
		*data-- = spi (0x00);				// read all the bytes and store
		}

#asm("sei");
	SELECT_7754 = 1;						// de-select '7754 energy meter
	return (1);								// success
}
// **************************************************************************
// *	M E T E R _ D U M P
// **************************************************************************
//
//	"addr" is an ADE7754 register number.  Output the value up to 2 bytes
//	in Modbus MSByte-first order to the character pointer.  Use the
//	ee_reg_7754 array to figure out how wide the register is.
//
unsigned char				meter_dump			(unsigned char addr,
												unsigned char * data)
{
unsigned char i;		// working variable

		i = ee_reg_7754[addr];
		if (i & MR_READ_OK)
			{
							// Mask off the length bits.
							// These registers all have MR_SPI_* == MR_BYTE_*.
			i &= 0x03;

			SELECT_7754 = 0;				// select '7754 energy meter
			#asm("cli");

			spi(addr);						// send op code
											// (which is register number in low 6 bits)
			if (i == 1)
				{
							// 8-bit register; one byte transfer & store
				*data++ = 0;	// null byte
				*data++ = spi (0x00);	// read the data byte and store
				}
			else
				{
							// 16-bit register; two byte transfer & store.
							//	MSB first.  If 24-bit, get the high 16 bits.
				*data++ = spi (0x00);	// read the data byte and store
				*data++ = spi (0x00);	// read the data byte and store
				}

			#asm("sei");
			SELECT_7754 = 1;						// de-select '7754 energy meter
			return (1);								// success
			}
		else
			{
			*data++ = 0;	// null byte
			*data++ = 0;	// null byte
			return (0);		// failure
			}

}
//
// **************************************************************************
// *	M E T E R _ W R I T E
// **************************************************************************
//
unsigned char				meter_write			(unsigned char addr,
												unsigned char * data,
												unsigned char count)
{
unsigned char i;	// working variable

	SELECT_7754 = 0;						// select '7754 energy meter
#asm("cli");
	spi(addr | 0x80);						// send op code
											// (which is register number in low 6 bits,
											//	plus high bit set indicating a write)
	for (i=0; i<count; i++)
		{
		spi(*data--);						// write all the bytes
		}
#asm("sei");

	SELECT_7754 = 1;						// de-select '7754 energy meter
	return (1);								// success
}
//
// **************************************************************************
// *	M E T E R _ I N I T
// **************************************************************************
//
//	Call for a software reset of the chip, per Rev. E errata.
//	Read back the chip revision number and return it,
//		as a kind of check that the chip is alive.
//
unsigned char				meter_init			(void)
{
unsigned char	i;	// working variable
unsigned int	j;	// working variable

	i = 0x44;
	meter_write (MR_OPMODE, &i, 1);		// OPMODE register, SWRST bit + DISCF bit
	delay_us (222);						// data sheet calls for 18us for sw reset
                 // [50us seems to be too short; 1ms seems to be plenty]
	meter_read (MR_RSTATUS,(unsigned char *) &j, 2);		// Read/clear STATUS after SWRST

	meter_read (MR_VERSION, &i, 1);		// VERSION register, 8 bits [expect 0x81]
	return (i);							// VERSION register contents to caller
}
//
// **************************************************************************
// *	M E T E R _ P U T
// **************************************************************************
//
//	Output a set of configuration registers to the ADE7754 Energy Meter chip.
//
//	Typically, this will be done at pwoer-on, since the chip is volatile.
//
//	Use the flags in the ee_reg_7754 array to write each writable register,
//	using the values contained in the given config_7754 structure.
//
//	Start at a 0 offset and first register.  For each register that is MR_WRITE_OK,
//		put the correct number of bytes from the given structure to the chip.
//
//	Note that the structure pointer is passed as a character pointer, since
//	only the offset and length will be used, not the field names.
//
unsigned char				meter_put			(unsigned char eeprom *config)
{
unsigned char	i;		// working variable
unsigned char	reg;	// register number
unsigned char	data1;	// one-byte data holder
unsigned int	data2;	// two-byte data holder
unsigned char	*addr;	// working address

	for (reg=0; reg < 64; reg++)
		{
		i = ee_reg_7754[reg];
		if (i & MR_WRITE_OK)
			{
							// Mask off the length bits.
							// These registers all have MR_SPI_* == MR_BYTE_*.
			i &= 0x03;
			if (i == 1)
				{
							// 8-bit register; one byte transfer & store
				data1 = *config;	// get the byte
				meter_write (reg, &data1, i);
				config++;
				}
			else
				{
							// 16-bit register; two byte transfer & store
				data2 = *((unsigned int eeprom*)config);
														// point to most significant byte
				addr = &(unsigned char)data2 + 1;
			  //	addr++;
				meter_write (reg, addr, i);	// and output the value
				config += 2;	// adjust the offset
				}
			}
		}

	return (1);				// Default success--no error checking each step
}

Usage fragments

 

...
		// Get working copies of the changeable bit masks for MMODE, MASK, & OPMODE
	meter_read (MR_MASK, (unsigned char *)&reg_mask, 2);
	meter_read (MR_MMODE, (unsigned char *)&reg_mmode, 1);
	meter_read (MR_OPMODE, (unsigned char *)&reg_opmode, 1);
...
Interrupt handling...
// **************************************************************************
// *	A D E 7 7 5 4   I R Q   A C K N O W L E D G E
// **************************************************************************
//
//	If an interrupt has been generated by the ADE7754,
//		read the STATUS register to acknowledge the interrupt, enable
//		further interrupts, and retreive the cause.
//
	if (service_needed_meter)
		{
		service_needed_meter = 0;	// clear the flag after processing

        retval = meter_read (MR_RSTATUS, (unsigned char *)&ADE7754_status+1, 2);	// get the 16 bits of status
        word0 = ADE7754_status;
		// The STATUS register has been loaded into 16 bit variables.
		//	The theory is that this should make for efficient code
		//	to check which event occurred, vs. checking for the bit
		//	in a 16 bit mask.  Readability suffers somewhat.
		//
		//	Note that more than one bit could be set, so each "if" is separate.
		//
		if (bank0_0)	//	AEHF	-- AENERGY register half-full
			{
			}
		if (bank0_1)	//	SAGA	-- line voltage sag, phase A
			{
			}
		if (bank0_2)	//	SAGB	-- line voltage sag, phase B
			{
			}
		if (bank0_3)	//	SAGC	-- line voltage sag, phase C
			{
			}
		if (bank0_4)	//	ZXTOA	-- zero crossing timeout, phase A
			{
			}
		if (bank0_5)	//	ZXTOB	-- zero crossing timeout, phase B
			{
			}
		if (bank0_6)	//	ZXTOC	-- zero crossing timeout, phase C
			{
			}
		if (bank0_7)	//	ZXA		-- zero crossing phase A
			{
			if (phase_state == PHASE_STATE_A)
				{
		        phase_time_a = phase_time; // store timer 2 tick count, channel b to a
		//	Get the per-phase RMS current and voltage values
    	    	meter_read (MR_AVRMS, &msg_param.u8[3], 3);
        		signal_avrms = msg_param.u16[1];

	        	meter_read (MR_AIRMS, &msg_param.u8[3], 3);
	    	    signal_airms = msg_param.u16[1];

			// move on to phase C
		        reg_mask &= ~(MR_STATUS_ZXA | MR_STATUS_ZXB | MR_STATUS_ZXC);
        		reg_mask |=	MR_STATUS_ZXC;
        		meter_write (MR_MASK, (unsigned char *)&reg_mask+1, 2);
	 			phase_state = PHASE_STATE_C;

				phase_found = 1;
				}
			}

		if (bank1_0)	//	ZXB		-- zero crossing phase B
			{
			if (phase_state == PHASE_STATE_B)
				{
	    	    TCCR2 = PHASE_TCCR2;		// set up for faster tick

		//	Get the per-phase RMS current and voltage values
    	    	meter_read (MR_BVRMS, &msg_param.u8[3], 3);
        		signal_bvrms = msg_param.u16[1];

	        	meter_read (MR_CIRMS, &msg_param.u8[3], 3); // signals swapped into '7754
	    	    signal_birms = msg_param.u16[1];

			// move on to phase A
		        reg_mask &= ~(MR_STATUS_ZXA | MR_STATUS_ZXB | MR_STATUS_ZXC);
        		reg_mask |=	MR_STATUS_ZXA;
        		meter_write (MR_MASK, (unsigned char *)&reg_mask+1, 2);
	 			phase_state = PHASE_STATE_A;

				phase_found = 1;
				}

			}
		if (bank1_1)	//	ZXC		-- zero crossing phase C
			{
			if (phase_state == PHASE_STATE_C)
				{
		        phase_time_c = phase_time; // store timer 2 tick count, channel a to c
                phase_time_b = phase_time;	// TEMPORARY ***

		//	Get the per-phase RMS current and voltage values
		        meter_read (MR_CVRMS, &msg_param.u8[3], 3);
    		    signal_cvrms = msg_param.u16[1];

//        		meter_read (MR_CIRMS, &msg_param.u8[3], 3);
	        	meter_read (MR_BIRMS, &msg_param.u8[3], 3); // signals swapped into '7754
	        	signal_cirms = msg_param.u16[1];
		        TCCR2 = 0;	// all done with timer 2 for this cycle of the process
			// completed; disable zero crossing interrupt enable
	        	reg_mask &= ~(MR_STATUS_ZXA | MR_STATUS_ZXB | MR_STATUS_ZXC);
	        	meter_write (MR_MASK, (unsigned char *)&reg_mask+1, 2);
 				phase_state = PHASE_STATE_CONT;	// data gathered; CONTinue with analysis


				phase_found = 1;
				}
			}

		if (bank1_2)	//	LENERGY	-- LINCYC line cycles completed
			{
			}
		// [RESET not applicable]
		if (bank1_4)	//	PKV		-- peak voltage exceeded
			{
			}
		if (bank1_5)	//	PKI		-- peak current exceeded
			{
			}
		if (bank1_6)	//	WFSM	-- waveform available
			{
			}
		if (bank1_7)	//	VAEHF 	-- VAENERGY register half-full
			{
			}


		}

...
some variables
...
//
// **************************************************************************
//	Application signal registers -- voltage
// **************************************************************************
unsigned int			signal_avrms;	// Phase A RMS voltage
unsigned int			signal_bvrms;	// Phase B RMS voltage
unsigned int			signal_cvrms;	// Phase C RMS voltage
unsigned int			v_ave;			// phase average, high 16 bits of pVRMS
// 80
unsigned int			v_unba;			// phase a unbalance from v_ave
unsigned int			v_unbb;			// phase b unbalance from v_ave
unsigned int			v_unbc;			// phase c unbalance from v_ave
unsigned int			v_unb;			// greatest phase unbalance from v_ave

... some usage of the above...
// **************************************************************************
// *	Current
// **************************************************************************

  if (count_since_attn <= 0)
   {
		// When the attenuator (ATTN) changes state, hold off any new
		//	processing of current channel signals for about 1 second

//	If the current attenuator circuit is engaged, then all signals must be
//	multiplied by 8.  Use the output port bit itself as a flag.

	if (ATTN)
		{
		if (signal_airms < 8000)
			{
			// careful to not overflow the unsigned int with the multiply
			signal_airms *= 8;
			}
		else
			{
			signal_airms = 60000;
			}
		if (signal_birms < 8000)
			{
			// careful to not overflow the unsigned int with the multiply
			signal_birms *= 8;
			}
		else
			{
			signal_birms = 60000;
			}
		if (signal_cirms < 8000)
			{
			// careful to not overflow the unsigned int with the multiply
			signal_cirms *= 8;
			}
		else
			{
			signal_cirms = 60000;
			}
		}

	tp_signal[TP_OC] =	0;
	tp_signal[TP_UC] = 9999;

	if (signal_airms > 	tp_signal[TP_OC])
		{
		tp_signal[TP_OC] = signal_airms;
		}
	if (signal_airms < 	tp_signal[TP_UC])
		{
		tp_signal[TP_UC] = signal_airms;
		}

	if (signal_birms > 	tp_signal[TP_OC])
		{
		tp_signal[TP_OC] = signal_birms;
		}
	if (signal_birms < 	tp_signal[TP_UC])
		{
		tp_signal[TP_UC] = signal_birms;
		}

	if (signal_cirms > 	tp_signal[TP_OC])
		{
		tp_signal[TP_OC] = signal_cirms;
		}
	if (signal_cirms < 	tp_signal[TP_UC])
		{
		tp_signal[TP_UC] = signal_cirms;
		}

//	i_ave = (signal_airms+signal_birms+signal_cirms+2)/3; <== overflowed 16 bits w/ 20,000+ counts/phase
	i_ave = (unsigned int)(((unsigned long)signal_airms+
							(unsigned long)signal_birms+
							(unsigned long)signal_cirms+2l)/3l);

In other words, I'm just showing you a bit on how to interface to this series of devices.
What registers >>you<< need to use, and what >>you<< do with them, is up to >>you<<.

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note:  To get good current readings, you must (IME) read right after zero-crossing, as indicated in the '7754 driver above.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Theusch

Thanks a lot for your kind help

I was working on my hardware these days but when I saw that i can't get a good result from MCU, I decided to connect the Ic directly to parallel port of my PC and check it via the evaluation software first before i continue coding .

I checked the  temperature and it displayed "209" I heated the IC with a heater and saw that the temperature increased , but since the max temp is 255 , I was afraid that something might be wrong here . (is 209 an acceptable result in normal temperature of a room?)

then I connected the CT ( ac1030)  to current channel A and shorted the B and C current inputs . I used a 10 ohm resistor for the ct (as it was suggested in the evaluation board ) . 

 measured current flow using my multimeter : 142 mA

the result of the ADE 7758 on input A :14700 to 15100 (as shown in the attached print screen )

and though the B and C were shorted ,it displayed 355 and 420 for them too (and this numbers were not constant ) 

are this results acceptable ?

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

syavash_kasraeee wrote:

... I saw that i can't get a good result from MCU ...

 

 

 

I don't quite know what to say.  You must have had a reason for choosing to start a project with this device in the first place.  I gave you driver code above; in the end it is a straightforward SPI device.  Indeed, you must be able to program an AVR master for a "standard" SPI slave in order to succeed.  Do you have the proper SPI setup?  DORD, CPHA, CPOL match the device?  Bit-rate appropriate?  /SS on the AVR taken care of properly?  (IIRC, I kept working to do a single read of a known register value, such as version.  Once that was repeatable and reliable, then I moved on to more general reading.)

 

I have no idea how your "parallel port" interface works.  It bit-bangs the SPI at a slow rate?  Probably.

 

I get the feeling that an analogy is in order:  It almost seems like you want to build a race car to enter the Daytona 500 later this month, but your questions seem to be on the level "What is a wrench?".

 

I haven't used your particular part.  The interface, as mentioned, seems very similar to the parts in the same family that I worked with.  Let's start with your current measurement:

 measured current flow using my multimeter : 142 mA

the result of the ADE 7758 on input A :14700 to 15100 (as shown in the attached print screen )

and though the B and C were shorted ,it displayed 355 and 420 for them too (and this numbers were not constant ) 

are this results acceptable ?

And what did I say in #6?

theusch wrote:

Note:  To get good current readings, you must (IME) read right after zero-crossing, as indicated in the '7754 driver above.

 

Is your parallel-port lash-up doing that?  I think not.

 

A few hundred counts is the low 8 bits of a 24-bit reading.  What does the datasheet say about low bit resolution and accuracy?

 

On to temperature:

...I checked the  temperature and it displayed "209" ...

Is that your eval application just reporting the value in the 8-bit TEMP 0x11 register?   In decimal?  Or converted to a temperature?

 

What does the datasheet say about such a conversion?

 

That certainly suggests that you have to take a "calibration" reading first at a known temperature, and then apply 3 degrees C per count from there.  That said, 209 is 0xd1 -- quite near the top of the range.  Was your chip already running hot?

 

...but since the max temp is 255 , I was afraid that something might be wrong here . ...

 

Doesn't the datasheet excerpt above address that?

 

Depending on the nominal value of the register, some finite
temperature can cause the register to roll over. This should be
compensated for in the system master (MCU).

 

The first guess is that you >>established<< that 209 is the nominal base value, unless your chip was already running hot.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Wed. Feb 10, 2016 - 08:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

syavash_kasraeee wrote:
and though the B and C were shorted ,it displayed 355 and 420 for them too (and this numbers were not constant ) are this results acceptable ?

What does the datasheet say?

The IRMS measurement is undefined at zero input. Calibration
of the offset should be done at low current and values at zero
input should be ignored.

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

I din't know what to say ... I was surprised when I saw your replies ... you have spent a lot of time for me and I'm very thankful

theusch wrote:

 I gave you driver code above; in the end it is a straightforward SPI device

Since I didn't have access to internet , I decided to save time and run another test by parallel port meanwhile to check whether my hardware is ok or not before seeing your replies ... Now I'm going to work on your precious codes.

theusch wrote:

 It almost seems like you want to build a race car to enter the Daytona 500 later this month, but your questions seem to be on the level "What is a wrench?".

Exactly ! I have been workin on smart card solutions (RFID , MIFARE , UHF ...) during these 5 years and this made me far from Spi and ... so these days i'm reviewing my basic knowledge about this as well .

theusch wrote:

I have no idea how your "parallel port" interface works.  It bit-bangs the SPI at a slow rate?  Probably.

This idea came to my mind when I saw the evaluation board . (although the eval board has several opto isolation and schmitt triggers) And it worked ! the software found the hardware and checked the version of ADE7758 then displayed the message that the Ic version is the latest . so I thought that the communication between hard and soft must be ok .

theusch wrote:

Was your chip already running hot?

no the chip is in a normal temperature an even not warm ! when I saw its quite near the top of the range , this made me amazed too . 

 

What about the measured current value ? (15000) 

Is it acceptable ?

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi again

I finally succeeded in communicating with this IC and read the Temp , freq, Voltage and current of the phases successfully and did the calibrations (with special Thanks to theusch )

but I'm somehow confused about what i must do to the power registers, i can read them but i get different values each time I read their values , so how can I set their offset and do the calibration and ... I'm totally confused about the procedure  and about how i can get the consumed energy during a 10 minute time . shall I add the values i get from these registers during time ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

syavash_kasraeee wrote:
...the power registers,...

 

Which power registers are you reading?  What does the datasheet say?  (About half the datasheet deals directly or indirectly with power, as this chip is aimed at energy billing.)

 

 

...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm much too sorry to disappoint you ... but although I have read these sections and even read the "smart metering Design" book too , I was unable to understand what I must do. 

I'm now working on one input (A phase ) reading the AWATTHR , AVARHR,AVAHR in a 0.5 second timer . Consider that my Aim is to make a Home energy meter (exactly what is written in the monthly bills)

What are the next steps now ? what should I do with these values ? 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As it was used in the ADE7758 evaluation board , i have used attenuation network resistor , a 1M and a 1K ohm to make a 220mv from the 220V voltage line . I have checked my resistors and they are axact . but when i get the voltage by an oscilloscope , it shows 235mv in the output . besides these i get 215 in my ADE7758. Can anyone help me where the problem is ? is the internal resistance of the ADE makes this difference in oscilloscope ?