Major Project- II (EE499) SMART ENERGY METER Project Report Submitted by Viraj N H - 13EE251 Suchith J N - 13EE147 G Rohit - 13EE215 Shreyas R - 13EE245 Bhargav D R - 13EE109 Under the Guidance of Dr. Manjunatha Sharma K. (DEC 2016 - APRIL 2017) DEPARTMENT OF ELECTRICAL AND ELECTRONICS ENGINEERING NATIONAL INSTITUTE OF TECHNOLOGY KARNATAKA SURATHKAL 1 DECLARATION by the B.Tech. Student We hereby declare that the Project Work entitled “Smart Energy Meter” which is being submitted to the National Institute of Technology Karnataka, Surathkal for the award of the Degree of Bachelor of Technology in Electrical and Electronics Engineering is a bonafide report of the work carried out by us. The material contained in this Project Work Report has not been submitted to any University or Institution for the award of any degree. S.No. Register Number Name of the Student 1 13EE109 Bhargav D R 2 13EE147 Suchith J N 3 13EE215 G Rohit 4 13EE245 Shreyas R 5 13EE251 Viraj N H Signature Department of Electrical and Electronics Engineering Place: NITK Surathkal Date: 2 CERTIFICATE This is to certify that the B.Tech Project Work Report entitled “Smart Energy Meter” submitted by : S.No. Register Number Name of the Student 1 13EE109 Bhargav D R 2 13EE147 Suchith J N 3 13EE215 G Rohit 4 13EE245 Shreyas R 5 13EE251 Viraj N H Signature as the record of the work carried out by them, is accepted as the B.Tech Project Work Report submission in partial fulfilment of the requirements for the award of degree of Bachelor of Technology in Electrical and Electronics Engineering Guide: Dr. Manjunatha Sharma K (Signature with Date) Chairman - DUGC (Signature with Date and Seal) 3 Abstract The Energy Meter is considered to the point of revenue collection for the utilities so it is necessary for them to make it fair and accurate so that both customers and Utility organization is good with the economics. The Smart Energy meter does both the job and meets the today’s demand of luxury and economy since no one is required to make the billing by locally getting to the load point. In our project we are making a detailed design and construction of smart meter to measure the single phase quantities. The meter can measure Energy, Power, Frequency, Power factor, Voltage and Current and then it is communicated to the remote server and the data is collected instantaneously. The first step of our project begins with the process diagram which gives the general idea of the next process to be done. The process diagram is then put in a circuit (Implemented) and then the results are monitored then the errors are noted down from each section, then the troubleshooting of each section is carried to make the results accurate. The final stage if the project is Implementing the final circuit after troubleshooting with the errors to get the better results. 4 Table of Contents 1. 2. About Smart Meter 8 1.1. Introduction 8 1.2. Overview 8 1.3. History 9 1.4. Purpose 10 Preliminary Design Stage 11 2.1. Preliminary Block Diagram 11 2.2. Concepts 11 2.2.1. Hall effect 12 2.2.2. Opamp 741 Circuit 12 2.2.3. Passive RC filter 13 2.2.4. UART 14 2.2.5. S/N ratio 18 2.3. Microcontroller 19 2.3.1. Hardware 19 2.3.2. Software 21 2.4. Board computer 22 2.5. GPIO 23 2.6. Software 23 3. Implementation 25 3.1. Sensor Circuit 3.1.1. Hall effect Voltage Sensor (LV25-P) 25 3.1.2. Hall effect Current Sensor (LA55-P) 27 3.1.3. Linearity Test 28 3.1.3.1. Voltage sensor linearity test 5 25 28 3.1.3.2. Current sensor linearity test 3.1.4. Sensors rigged on the PCB 30 3.2. Level Shifter with Filter Circuit 31 3.3. Microcontroller 33 3.4. LCD Display (HD44780) 35 3.5. Software 38 3.5.1. GPIO API 38 3.5.2. LCD API 38 3.5.3. Driver 39 3.5.1.1. Initilization 39 3.5.1.2. Receive and process sub-component 40 3.5.1.3. Display sub-component 42 3.5.1.4. Communication sub-component 43 3.5.4. Server software 3.6. Complete Circuit Diagram 4. Troubleshooting 44 44 45 4.1. Hardware 45 4.1.1. Soldering 45 4.1.2. Noise from the Level Shifter 46 4.1.3. Communication Error 46 4.1.4. Sampling reference 49 4.2. Software 6 29 50 4.2.1. GPIO troubleshooting 51 4.2.2. LCD troubleshooting 51 4.2.3. Driver troubleshooting 52 4.2.3.1. Splitting the work among different cores 52 4.2.3.2. Long critical section in Display module 52 4.2.3.3. Handling blocking accept() function 53 4.2.3.4. Serial Communication settings 54 4.2.3.5. Detecting valid zero crossings 54 4.3. Final Circuit Diagram 5. Results 56 5.1. Sensor Output 56 5.2. Level shifter with filter output 57 5.3. LCD Display output 59 5.4. Remote Device output 60 5.5. Conclusion 60 6. Future improvements 61 6.1. Hardware 61 6.2. Software 62 7. Application (s) 63 7.1. Automatic Billing 63 7.2. Alerting System 63 8. References 7 55 64 1. About Smart Meter Fig. 1 1.1. Introduction A smart meter is an electronic device that records consumption of electric energy in intervals of an hour or less and communicates that information at least daily back to the utility for monitoring and billing. Smart meters enable two-way communication between the meter and the central system. Unlike home energy monitors, smart meters can gather data for remote reporting. Such an advanced metering infrastructure (AMI) differs from traditional automatic meter reading (AMR) in that it enables two-way communications with the meter. 1.2. Overview The term Smart Meter often refers to an electricity meter, but it also may mean a device measuring natural gas or water consumption. Similar meters, usually referred to as interval or time-of-use meters, have existed for years, but "Smart Meters" usually involve real-time or near real-time sensors, power outage 8 notification, and power quality monitoring. These additional features are more than simple automated meter reading (AMR). They are similar in many respects to Advanced Metering Infrastructure (AMI) meters. Interval and time-of-use meters historically have been installed to measure commercial and industrial customers, but may not have automatic reading. Research by Which?, the UK consumer group, showed that as many as one in three confuse smart meters with energy monitors, also known as in-home display monitors. The roll-out of smart meters is one strategy for energy savings. While energy suppliers in the UK could save around £300 million a year from their introduction, consumer benefits will depend on people actively changing their energy use. For example, time of use tariffs offering lower rates at off-peak times, and selling electricity back to the grid with net metering, may also benefit consumers. The installed base of smart meters in Europe at the end of 2008 was about 39 million units, according to analyst firm Berg Insight. Globally, Pike Research found that smart meter shipments were 17.4 million units for the first quarter of 2011. Visiongain has determined that the value of the global smart meter market will reach $7bn in 2012. Smart meters may be part of a smart grid, but alone, they do not constitute a smart grid. 1.3. History In 1972, Theodore George "Ted" Paraskevakos, while working with Boeing in Huntsville, Alabama, developed a sensor monitoring system that used digital transmission for security, fire, and medical alarm systems as well as meter reading capabilities. This technology was a spin-off of the automatic telephone line identification system, now known as Caller ID. In 1974, Paraskevakos was awarded a U.S. patent for this technology. In 1977, he launched Metretek, Inc., which developed and produced the first fully automated, commercially available remote meter reading and load management system. Since this system was developed pre-Internet, Metretek utilized the IBM series 1 mini-computer. For this approach, Paraskevakos and Metretek were awarded multiple patents. 9 1.4. Purpose Since the inception of electricity deregulation and market-driven pricing throughout the world, utilities have been looking for a means to match consumption with generation. Traditional electrical and gas meters only measure total consumption, and so provide no information of when the energy was consumed at each metered site. Smart meters provide a way of measuring this site-specific information, allowing utility companies to introduce different prices for consumption based on the time of day and the season. Utility companies propose that from a consumer perspective, smart metering offers potential benefits to householders. These include, a) an end to estimated bills, which are a major source of complaints for many customers b) a tool to help consumers better manage their energy purchases - stating that smart meters with a display outside their homes could provide up-to-date information on gas and electricity consumption and in doing so help people to manage their energy use and reduce their energy bills. Electricity pricing usually peaks at certain predictable times of the day and the season. In particular, if generation is constrained, prices can rise if power from other jurisdictions or more costly generation is brought online. Proponents assert that billing customers at a higher rate for peak times will encourage consumers to adjust their consumption habits to be more responsive to market prices and assert further, that regulatory and market design agencies hope these "price signals" could delay the construction of additional generation or at least the purchase of energy from higher priced sources, thereby controlling the steady and rapid increase of electricity prices. There are some concerns, however, that low income and vulnerable consumers may not benefit from intraday time-of-use tariffs. An academic study based on existing trials showed that homeowners' electricity consumption on average is reduced by approximately 3-5%. The ability to connect/disconnect service and read meter consumption remotely are major labor savings for the utility and can result in large layoffs of meter readers. 10 2. Preliminary Design stage In this stage the preliminary design of the processes diagram is carried out and the circuit is rigged up to test in the real time load and the data is tabulated to make the necessary changes in the next stage of design after troubleshooting. 2.1. Preliminary Block Diagram Fig. 2.1 2.2. Concepts The fundamentals required to carry the preliminary processes to the implementation stage in selection of the appropriate hardware and the technique to condition the signal that is available from the sensors with increasing S/N ratio and attain better accuracy. Since the signal is always weak and are easily distorted by small amount of noise, getting better S/N ratio till the signal is sampled is the primary goal and this involves taking care of all the hardware and its behaviour to the external environment. Then applying some signal processing techniques to increase the S/N ratio. 11 2.2.1. Hall effect Fig. 2.2.1 The Hall effect is the production of a voltage difference (the Hall voltage) across an electrical conductor, transverse to an electric current in the conductor and to an applied magnetic field perpendicular to the current. The Hall coefficient is defined as the ratio of the induced electric field to the product of the current density and the applied magnetic field. It is a characteristic of the material from which the conductor is made, since its value depends on the type, number, and properties of the charge carriers that constitute the current. 2.2.2. Opamp 741 Circuit Fig. 2.2.2 12 The 741 IC (integrated Circuit) which is commonly called as Opamp (operational amplifier) is used here to level shift the circuit and to provide the high input impedance for the signal from the sensor which reduces the loading on the sensor circuit. This IC has a great noise cancellation effect when negative feedback is applied and this greatly improves the signal to noise ratio. 2.2.3. Passive RC filter This is first order RC passive filter circuit, with different settings for Resistor and Capacitor the filtering of the frequency takes place, but it also comes with the reduction in amplitude of the input voltage so deciding the Vout/Vin ration is important. Calculation to get a desired 3dB frequency : At 3dB frequency |Vout/Vin | = 1/sqrt(2) Vout/Vin = XC/(XC + R) Here XC = 1/(2*pi*f*C); After substituting we get, Vout/Vin = 1/(1+2*pi*f*C*R) |Vout/Vin| = 1/sqrt(1+ 2*pi*f*C*R) At 3dB frequency From (1) => 1+2*pi*f*C*R = 2 => f = 1/(2*pi*R*C) This is the cutoff frequency and the voltage reduction from this point is 20dB/decade (on logarithmic scale) 13 2.2.4. UART UART stands for Universal Asynchronous Receiver Transmitter, in UART communication, two UARTs communicate directly with each other. The transmitting UART converts parallel data from a controlling device like a CPU into serial form, transmits it in serial to the receiving UART, which then converts the serial data back into parallel data for the receiving device. Only two wires are needed to transmit data between two UARTs. Data flows from the Tx pin of the transmitting UART to the Rx pin of the receiving UART: Fig. 2.2.4.1 UARTs transmit data asynchronously, which means there is no clock signal to synchronize the output of bits from the transmitting UART to the sampling of bits by the receiving UART. Instead of a clock signal, the transmitting UART adds start and stop bits to the data packet being transferred. These bits define the beginning and end of the data packet so the receiving UART knows when to start reading the bits. When the receiving UART detects a start bit, it starts to read the incoming bits at a specific frequency known as the baud rate. Baud rate is a measure of the speed of data transfer, expressed in bits per second (bps). Both UARTs must operate at about the same baud rate. The baud rate between the transmitting and receiving UARTs can only differ by about 10% before the timing of bits gets too far off. Both UARTs must also must be configured to transmit and receive the same data packet structure. 14 How UART works? UART transmits/receives the data through the data bus. The data bus is used to send data to the UART by another device like a CPU, memory, or microcontroller. Data is transferred from the data bus to the transmitting UART in parallel form. After the transmitting UART gets the parallel data from the data bus, it adds a start bit, a parity bit, and a stop bit, creating the data packet. Next, the data packet is output serially, bit by bit at the Tx pin. The receiving UART reads the data packet bit by bit at its Rx pin. The receiving UART then converts the data back into parallel form and removes the start bit, parity bit, and stop bits. Finally, the receiving UART transfers the data packet in parallel to the data bus on the receiving end. Fig. 2.2.4.2 UART transmitted data is organized into packets. Each packet contains 1 start bit, 5 to 9 data bits (depending on the UART), an optional parity bit, and 1 or 2 stop bits 15 START BIT The UART data transmission line is normally held at a high voltage level when it’s not transmitting data. To start the transfer of data, the transmitting UART pulls the transmission line from high to low for one clock cycle. When the receiving UART detects the high to low voltage transition, it begins reading the bits in the data frame at the frequency of the baud rate. DATA FRAME The data frame contains the actual data being transferred. It can be 5 bits up to 8 bits long if a parity bit is used. If no parity bit is used, the data frame can be 9 bits long. In most cases, the data is sent with the least significant bit first. PARITY Parity describes the evenness or oddness of a number. The parity bit is a way for the receiving UART to tell if any data has changed during transmission. Bits can be changed by electromagnetic radiation, mismatched baud rates, or long distance data transfers. After the receiving UART reads the data frame, it counts the number of bits with a value of 1 and checks if the total is an even or odd number. If the parity bit is a 0 (even parity), the 1 bits in the data frame should total to an even number. If the parity bit is a 1 (odd parity), the 1 bits in the data frame should total to an odd number. When the parity bit matches the data, the UART knows that the transmission was free of errors. But if the parity bit is a 0, and the total is odd; or the parity bit is a 1, and the total is even, the UART knows that bits in the data frame have changed. STOP BITS To signal the end of the data packet, the sending UART drives the data transmission line from a low voltage to a high voltage for at least two bit durations. STEPS OF UART TRANSMISSION 1. The transmitting UART receives data in parallel from the data bus 16 Fig. 2.2.4.2. 2. The transmitting UART adds the start bit, parity bit, and the stop bit(s) to the data frame Fig. 2.2.4.3 3. The entire packet is sent serially from the transmitting UART to the receiving UART. The receiving UART samples the data line at the pre-configured baud rate Fig. 2.2.4.4 4. The receiving UART discards the start bit, parity bit, and stop bit from the data frame 17 Fig, 2.2.4.5 5. The receiving UART converts the serial data back into parallel and transfers it to the data bus on the receiving end Fig. 2.2.4.6 2.2.5. S/N ratio In analog and digital communications, signal-to-noise ratio, often written S/N or SNR, is a measure of signal strength relative to background noise. The ratio is usually measured in decibels (dB) using a signal-to-noise ratio formula. If the incoming signal strength in microvolts is Vs, and the noise level, also in microvolts, is Vn, then the signal-to-noise ratio, S/N, in decibels is given by the formula: S/N = 20 log10(Vs/Vn). If Vs = Vn, then S/N = 0. In this situation, the signal borders on unreadable, because the noise level severely competes with it. In digital communications, this will probably cause a 18 reduction in data speed because of frequent errors that require the source (transmitting) computer or terminal to resend some packets of data. Ideally, Vs is greater than Vn, so a high signal-to-noise ratio is positive. As an example, suppose that Vs = 10.0 microvolts and Vn = 1.00 microvolt. Then: S/N = 20 log10(10.0) = 20.0 dB This results in the signal being clearly readable. If the signal is much weaker but still above the noise -- say, 1.30 microvolts -- then: S/N = 20 log10(1.30) = 2.28 dB This is a marginal situation. There might be some error in reading the signal of fundamental frequency. This ratio is very important because we are here interested only in fundamental frequency quantity measurement, so if other frequency components gets into the system then the noise in the system increases which reduces the S/N ratio. 2.3. Microcontroller 2.3.1. Hardware MSP430F5529LP : is a 16 bit microcontroller which can be clocked up to 25MHz of frequency with its internal DCO (Digitally controlled oscillator). Its has FLL (Frequency locked loop) technology to control the DCO frequency and set it a particular value. This has a 12 bit one sampling core to perform ADC (Analog to Digital Conversion) with 16 channels. The FET (Flash emulator tool) which bridges between MSP430F5529 microcontroller with computer supports USB 2.0 and a maximum baud rate of 115200. 19 Fig. 2.3.1.1 Arduino Uno (Atmega328P) : Arduino Uno is a microcontroller board based on the ATmega328P. It has 14 digital input/output pins (of which 6 can be used as PWM outputs), 6 analog inputs, a 16MHz quartz crystal, a USB connection, a power jack, an ICSP header and a reset button. It contains everything needed to support the microcontroller; simply connect it to a computer with a USB cable or power it with a AC-to-DC adapter or battery to get started.. You can tinker with your UNO without worrying too much about doing something wrong, worst case scenario you can replace the chip for a few dollars and start over again. It can support up to 115200 baud rate but can go up to 460800 baud rate with added excess error of around 15-20%. 20 Fig. 2.3.1.2 2.3.2. Software MSP430F5529LP: Code composer studio (CCS) is the open source IDE (Integrated development Environment) by Texas Instruments Inc. helps in programming the device through the USB serial port which uses Embedded C language. The alternative option of Energia is available to program the device with some compromise in the access to all the hardware available in the device but with the user friendly libraries. Arduino Uno (Atmega 328P): Arduino v1.6 is the latest open source IDE available to program the device which has a user friendly libraries, programming is based on the C language. 21 2.4. Board computer Fig. 2.4 PINE A64 is Single Board Computer powered by Quad-Core ARM Cortex A53 64-Bit Processor. It provides PI-2 Bus, Euler Bus and many others peripheral devices interface for makers to integrate with sensors and devices. Various Operating System (OS) are made available by open source community such Mainline Kernel, Linux Distro, Android, Remix OS, Windows IoT and many more to come. It has the following features ● 1.2 Ghz Quad-Core ARM Cortex A53 64-Bit Processor. Executes both 64 and 32 Bit for scalable high performance. 22 ● Dual I/O expansion slots ● Dual Core Mali 400 MP2 Graphics card ● 512MB DDR3 Memory ● Integrated Display engine with HDMI 1.4a ● 10/100Mbps Ethernet Port We have used Ubuntu 16.04 which is a Linux based Operating System with MATE desktop environment. 2.5. GPIO GPIO stands for General Purpose Input Output. Pine-64 has 28 GPIO ports. Because of “everything is a file” view in Linux based systems, GPIO ports are represented as files and they can be read from or written to using File based I/O techniques which are quite common. Before using a GPIO port, it has to be initialized. Here is a small shell script we used to turn a GPIO pin specified by <PORT-NO> to high. # echo <PORT-NO> > /sys/class/gpio/export # echo “out” > /sys/class/gpio/gpio<PORT-NO>/direction # echo “1” > /sys/class/gpio/gpio<PORT-NO>/value The first line registers the GPIO pin specified by PORT-NO with the system. The second line specifies that the port is an output port. The third line sets the value at the GPIO port to be high. Replacing “0” in place of “1” would turn it low. An LED is connected to the GPIO pin and it glows when the value is high. 2.6. Software Sampler is responsible for getting samples of voltage and current and formatting the data. Each sample obtained is broken down into 4 bytes and sent to the driver. Sampler is either MSP430 or Arduino. Display is responsible for showing the values like Energy, Current and Voltage (RMS), Power, Frequency, Power factor. Values are displayed in LCD. Server is where all data from the board computer goes. There is also a remote terminal through which one can connect to the device and ask for instantaneous values. This program runs in a remote computer. 23 Fig. 2.6 Driver is a software component which controls and coordinates various functionalities of the system. This software runs in the board computer. It contains three sub-components. 1. Data processor module: Receive voltage and current data and check for errors. Then process it to compute power, frequency, energy etc. 2. LCD module: It is responsible for controlling the LCD. It is tasked with displaying instantaneous values on the LCD screen. 3. Communication module: It is responsible for communicating with the server. It sends instantaneous data to the remote server through the network. (Currently we are using intranet) 24 3. Implementation With the help of the concepts from section 2.2. We implement each section of the Process as shown in the block diagram in section 2.1. By the selection of the appropriate components and devices to meet the desired requirement of Indian standards for Advanced Metering Infrastructure (AMI). 3.1. Sensor CIrcuit Here the hall effect sensors are used to step down and sense the values. Both voltage and current sensor gives current as the output parameter and input is also the current. So it is required to setup the proper circuit to get the voltage signals out of that current. 3.1.1. Hall effect Voltage Sensor (LV25-P) Fig. 3.3.1.1 Required Parameter Required Rating Rating of the sensor Voltage in rms 250V 500V Output voltage in rms 0.8839V 25mA*190ohm = 4.75V Since the rating of the sensor is above the required value it is selected for our project. 25 The sensor requires +12V and -12V supply for the operation. The selection of the value of the resistor is done with the help of the data sheet and it is recommended that the resistance must be within a range of 30 to 190 ohm. Calculation of the resistor values (RM , R1) : IPN = VIN/R1 VIN = 250V, R1 is chosen such a way that IPN <10mA, so let R1 = 36kohm IPN = 6.94mA Conversion ratio from the datasheet is 2500:1000 IS = 2500*IPN/1000 = 17.36mA Required voltage for the sampler is 2.5 p-p So RM = 2.5/(sqrt(2)*2*17.36mA) = 50.91 ohm So RM < 50.91 ohm, so we have chosen RM = 47ohm Circuit Diagram FIg. 3.3.1.2 26 3.1.2. Hall effect Current Sensor Fig. 3.1.2.1 Required Parameter Required Rating Rating of the sensor Input Current in rms 30A 50A Output voltage in rms 0.8839V 25mA*100ohm = 2.5V Since the rating of the sensor is above the required value it is selected for our project. The sensor requires +12V and -12V supply for the operation. The selection of the value of the resistor is done with the help of the data sheet and it is recommended that the resistance must be within a range of 10 to 100 ohm. Calculation of the resistor value (RM ): Conversion ratio from the datasheet is 1:1000 IPN = 30A IS = 30A/1000 = 30mA Required voltage for the sampler is 2.5 p-p So RM = 2.5/(sqrt(2)*2*30mA) = 29.46 ohm So RM < 29.46 ohm, so we have chosen RM = 22ohm 27 Circuit Diagram FIg. 3.1.2.2 3.1.3. Linearity Test This is a test to find out the transfer function linearity in RMS values. In this test the Sensor Output voltage in RMS is plotted against source voltage (VS) for voltage sensor and load current for current sensor(IS) 3.1.3.1. Voltage sensor linearity test 1. This is for measuring resistance RM = 47Ω , R1 = 47kΩ Fig. 3.1.3.1 (a) From this we can say that the transducer is linear for RM = 47Ω , slope = 1/397.4983 V/V 28 2. This is for measuring resistance RM = 120Ω , R1 = 47kΩ Fig 3.1.3.1 (b) From this we can say that the transducer is linear for RM = 120Ω , slope = 1/150.3799 V/V 3.1.3.2. Current sensor linearity test 1. This is for measuring resistance RM = 22Ω Fig. 3.1.3.2 (a) From this we can say that the transducer is linear for RM = 22Ω , slope = 1/46.2529 V/A 29 2. This is for measuring resistance RM = 47Ω Fig. 3.1.3.2 (b) From this we can say that the transducer is linear for RM = 47Ω , slope = 1/21.9865 V/A 3.1.4. Sensors rigged on the PCB Fig. 3.1.4 30 3.2. Level Shifter with Filter circuit This circuit gives the shift in the voltage of the sinusoidal signal received from the sensors and makes it positive and every instant, this is required for the microcontroller since microcontroller cannot sample the negative signals. Here the opamp (741) is employed for this task which has a better noise cancellation in negative feedback and provides high input impedance which reduces the load on sensors more about this is in section 2.2.2. The reference voltage of 1.25V is set using a 7805 voltage regulator IC followed by a potential divider circuit and this circuit is powered by a 9V DC transistor battery. Circuit Diagram: FIg. 3.2.1 Potential divider (PD): Vref = (1/(1/R+1/R+1/R))/(R + (1/(1/R+1/R+1/R)))*V7805 = ¾ *V7805 = ¾*5V = 1.25V Circuit Diagram: Fig. 3.2.2 31 Calculation of R1, R2, R3, R4: Grounding signal in, (non inverting amplifier configuration) Vo1 = (1+R2/R1)*(R3*Vref)/(R3+R4) ----- (1) Grounding Vref (non inverting amplifier configuration) Vo2 = (1+R2/R1)*(R4*Vsignal)/(R3+R4) ----- (2) Output, Vo = Vo1 + Vo2 From (1) and (2) Vo = (1+R2/R1)*(R3*Vref + R4*Vsignal)/(R3+R4) Setting R1=R2=R3=R4=R Vo = Vref + Vsignal\-* Let the value of R = 10Kohm Now the circuit with shift the voltage of the signal by Vref This level shifted circuit will have high frequency signals because of the component noise and other noise from the sensor which are other than the fundamental frequency so in order to extract only the fundamental frequency (approx.) we need to use a Low pass filter circuit this will help to increase S/N ratio. From the section 2.2.3. We need to calculate the value of R and C required to get the desired 3dB frequency. Desired 3db frequency must be above 50Hz, Let’s say the resistance R = 10Kohm and now to get a frequency above 50Hz what must be the value of capacitor Creq Creq = 1/(2*pi*f*R) = 3.18e-7F This closest value of capacitor available below Creq (since C is inversely proportional to f) is Cstandard = 0.1uF f3dB = 1/(2*pi*Cstandard*R) = 159.15Hz 32 This value is close enough to 50Hz so its chosen. The rigged up circuit on PCB: Fig. 3.2.3 3.3. Microcontroller The Microcontroller we used here is the Arduino Uno board with Atmega328P chip which has a 10 bit ADC (Analog to digital converter), with 6 ADC pins to sample the analog signal at a specified rate. Atmega328P has 28 pins out of which 14 are GPIO pins. It has 6 PWM pins which generates the analog waveforms of specified period. This purpose we are using it is to sample the signals from the sensor and then communicate these values with the Pine64 board through USB 2.0 serial port at a specified baud rate this communication protocol is called UART. Data from the arduino sending format: 33 Since the arduino has a 10 bit ADC, we cannot send all the 10 bits at once through the serial channel so we have divided the data as shown below with adding identification bits for bit 7 and bit 6 in the stage 3. Fig. 3.3 Reason for selection of UART: 1. It is easy to setup and communicate. 2. Changing the data transmission rate is much easier in Arduino 3. It can communicate with just 2 connected data lines between the device (Here between Arduino and Pine64) 4. The Arduino Uno board has a driver with hardware which interface with the Pine64 USB 2.0 so the data can be transmitted just by a USB cable which is used to power the Arduino. Limitations: 1. Only one byte of data can be sent at a time. 2. Higher data transmission rates typically above 115200 bits/sec increases errors in communication drastically. 34 3.4. LCD Display (HD44780) The Hitachi HD44780 LCD controller is an alphanumeric dot matrix liquid crystal display (LCD) controller developed by Hitachi that was commonly used during the MCS-51 era. It was made commercially available around year 1987. The character set of the controller includes ASCII characters, Japanese Kana characters, and some symbols in two 28 character lines. Using an extension driver, the device can display up to 80 characters. Fig. 3.4 The Hitachi HD44780 LCD controller is limited to monochrome text displays and is often used in copiers, fax machines, laser printers, industrial test equipment, networking equipment, such as routers and storage devices. Compatible LCD screens are manufactured in several standard configurations. Common sizes are one row of eight characters (8x1), and 16×2, 20×2 and 20×4 formats. Larger custom sizes are made with 32, 40 and 80 characters and with 1, 2, 4 or 8 lines. The most commonly manufactured larger configuration is 40x4. Characters, which requires two individually addressable HD44780 controllers with expansion chips as a single HD44780 chip can only address up to 80 characters. A common smaller size is 16×2, and this size is readily available as surplus stock for hobbyist and prototyping work. Character 35 LCDs may have a backlight, which may be LED, fluorescent, or electroluminescent. Character LCDs use a 16 contact interface, commonly using pins or card edge connections on 0.1 inch (2.54 mm) centers. Those without backlights may have only 14 pins, omitting the two pins powering the light. This interface was designed to be easily hooked up to the MCS-51 XRAM interface, using only two address pins, which allowed displaying text on LCD using simple MOVX commands, offering cost effective option for adding text display to devices. The pinout is as follows: 1. Ground 2. VCC (+3.3 to +5V) 3. Contrast adjustment (VO) 4. Register Select (RS). RS=0: Command, RS=1: Data 5. Read/Write (R/W). R/W=0: Write, R/W=1: Read 6. Clock (Enable). Falling edge triggered 7. Bit 0 (Not used in 4-bit operation) 8. Bit 1 (Not used in 4-bit operation) 9. Bit 2 (Not used in 4-bit operation) 10. Bit 3 (Not used in 4-bit operation) 11. Bit 4 12. Bit 5 13. Bit 6 14. Bit 7 15. Backlight Anode (+) (If applicable) 16. Backlight Cathode (-) (If applicable) The nominal operating voltage for LED backlights is 5V at full brightness, with dimming at lower voltages dependent on the details such as LED color. Non-LED backlights often require higher voltages. Mode Selection Selecting 4-bit or 8-bit mode requires careful selection of commands. There are two primary considerations. First, with D3-D0 unconnected, these lines will always appear low (0b0000) to the HD44780 when it is in 8-bit mode. Second, the LCD may initially be in one of three states: 36 • (State1) 8-bit mode • (State2) 4-bit mode, waiting for the first set of 4 bits • (State3) 4-bit mode, waiting for the second set of 4 bits State3 may occur, for example, if a prior control was aborted after sending only the first 4 bits of a command while the LCD was in 4-bit mode. The following algorithm ensures that the LCD is in the desired mode: 1. Set D7-D4 to 0b0011, and toggle the enable bit. 1. If in State1, the LCD will see the command as 0b0011_0000, and thus remain in 8-bit mode (State1). 2. If in State2, the LCD will simply latch the value 0b0011 into bits 7-4 and then move to State3. 3. If in State3, the LCD will latch the value 0b0011 into bits 3-0, and then execute a random command based on the (unknown to us) values in bits 7-4, after which it will either be in State1 (if the unknown bits happened to be 0b0011), or State2 (if the unknown bits were anything else). 2. Repeat the above, setting D7-D4 to 0b0011 and toggling the enable bit again. 1. If in State1, the LCD will remain in 8-bit mode (State1) just as above. 2. If in State2, it will latch the value into bits 7-4 and move to State3, just as above. 3. If in State3, the LCD will latch the value into bits 3-0 just as above and execute a command. However, the command will no longer be random, but will be the 0b0011 that was latched from State2 in the previous iteration. Thus, the LCD will switch to 8-bit mode and change to State1. 3. The LCD is now in either State1 or State 3. Repeat the previous step one more time. 1. If in State1, the LCD will remain in 8-bit mode (and thus State1). 2. The LCD can no longer be in State2 at this point. 3. If in State3, the LCD will latch the value into bits 3-0 and execute a command, which will be the 0b0011 that was latched from State2 in the previous iteration, thus switching the LCD to 8-bit mode and State1. 4. Now that the LCD is definitely in 8-bit mode, it can be switched to 4-bit mode if desired. To do so, set D7-D4 to 0b0010 and toggle the enable bit. This will leave the LCD in 4-bit mode, configured for a single line and 5x8 fonts. 37 5. Issue any desired additional Function Set commands to specify the number of lines and the font to use, being sure to use the appropriate value for bit 4 so as to remain in the desired mode (0 for 4-bit and 1 for 8-bit). Once in 4-bit mode, character and control data are transferred as pairs of 4-bit "nibbles" on the upper data pins, D7-D4. The four most significant bits (7-4) must be written first, followed by the four least significant bits (3-0). 3.5. Software 3.5.1. GPIO API typedef enum { IN,OUT } DIRECTION; typedef enum { LOW=0, HIGH=1 } PORT_VALUE; typedef int GPIO_PORT; typedef struct { GPIO_PORT no; FILE *handle; DIRECTION dir; }GPIO; void void void void DIRECTION GPIO_PORT void void gpio_init(void); gpio_finalize(void); gpio_open(GPIO *gpio, GPIO_PORT port, DIRECTION dir); gpio_close(GPIO *gpio); gpio_get_direction(GPIO *port); gpio_get_port_no(GPIO *port); gpio_set_direction(GPIO *port, DIRECTION dir); gpio_set_value(GPIO *port, PORT_VALUE val); This is the API used to handle GPIO ports. The functions gpio_init() and gpio_finalize() are used to export and unexport GPIO port files in sysfs. Export is needed before using GPIO pins through sysfs. Functions gpio_open() and gpio_close() are used to obtain and release handles to a particular GPIO port respectively. Rest are getters and setters for port direction and value. 3.5.2. LCD API typedef struct { GPIO data[8]; GPIO enable; GPIO rw, rs; }LCD; 38 typedef enum { INSTRUCTION=0, DATA=1 } LCD_RSH_MODE; typedef enum { READ=1, WRITE=0 } LCD_RW_MODE; typedef int LCD_COMMAND; void lcd_set_enable(LCD *disp, PORT_VALUE val); void lcd_set_readwrite(LCD *disp, LCD_RW_MODE val); void lcd_set_regshift(LCD *disp, LCD_RSH_MODE val); void void void void void lcd_send_command(LCD *disp, LCD_COMMAND cmd); lcd_send_data(LCD *disp, int data); lcd_send_text(LCD *disp, const char *text, int r, int c); lcd_init(LCD *lcd, GPIO data[8], GPIO enable, GPIO rw, GPIO rs); lcd_close(LCD *lcd); This is the API used to control LCD. Functions lcd_init() and lcd_close() are used to acquire and release GPIO ports required for them. The most important function used here is lcd_send_text() which is used to display the text given row and column. It is used by the driver sub-component. 3.5.3. Driver Driver software runs in Pine-64 board. It is the main program which is responsible for receiving data from the microcontroller, sending data to the server and displaying values in the meter. It depends on LCD and GPIO API. Each of the subcomponents run in a different threads which are bound to different cores. A thread is a unit of computation which shares the same address space as a process. Basically, it can be thought of as the lightweight process. We have used pthread (POSIX threads) library to deal with threads. The Operating System scheduler doesn’t guarantee that new threads are bound to a particular core. But there are non-standard extensions in pthread implementation in Linux which allows us to do that (pthread_setaffinity_np). It allows us to leverage the power of multiple cores in the system. The board we are using has 4 cores and we use 3 of them. One for each subcomponent. This design also allows us to add more functionality to the program by adding more threads since they execute independently while not compromising with the performance of the system. 3.5.1.1 Initialization First GPIO ports, LCD display and Serial ports are initialized. Then additional threads are created for LCD and Communication sub-components. Once the sub-components start, 39 they request the scheduler to set bind them to different cores. Then the main loop which waits for data from sampler starts. From this point of time, three threads will be running on three different cores. 3.5.1.2 Receive and process sub-component This component receives data from the sampler. For each record of voltage and current, 4 bytes has to be received. It receives it byte by byte instead of reading all 4 bytes at once because it is easy to handle errors this way. Once data is received it checks the sequence number (which is most significant two bits of data). If the sequence number is wrong, then the whole sample is discarded. The receiver is a finite state machine with 6 states Fig. 3.4.1.2 40 ● VOLTAGE_LOW and VOLTAGE_HIGH - Lower and higher bytes of voltage data. ● CURRENT_LOW and CURRENT_HIGH - Lower and higher bytes of current data. ● ERROR - If there is error in data, then this state is reached. ● PROCESS - Data received successfully If data is received successfully, then the voltage and current bytes are assembled discarding sequence numbers. It is then converted to the actual value by offsetting effects of level shifter and sampler. Computation of RMS values of current and voltage, power, frequency are triggered only at zero crossings. Zero crossing is detected by comparing the previous and current values of voltage. Only voltage zero crossing timestamps are recorded. Once certain number of zero crossings are recorded, computation of RMS values of current, voltage, power, energy, power factor are triggered. The time interval is the difference between the first and the last recorded zero crossing. It is needed to compute energy. Frequency is computed as the reciprocal of the average time for each cycle which again can be computed by zero crossing readings. It might happen that some zero crossing readings are lost. In order to handle such situations we compute if enough readings are available, else the readings are completely discarded. The number of zero crossing readings required to compute each quantity can be set in code. Code to compute RMS value of current, voltage, power, power factor and time elapsed double double double double double double v_rms = sqrt(v_squared_sum/n_samples); a_rms = sqrt(a_squared_sum/n_samples); real_pow = p_sum/n_samples; apparent_pow = v_rms * a_rms; power_factor = real_pow/apparent_pow; cycle_time = time_diff(vzstamps[0],vzstamps[vcnt-1]); V_squared_sum and a_squared_sum are reset after computation. They represent the sum of square of the voltage and current readings. The variable n_samples represent the number of samples considered for computing the quantity. The number of zero crossings considered for computing these quantities is denoted by the constant N_ZCROSS. Similarly, the number of zero crossings considered to compute frequency is N_CYCLES. Currently we have set N_ZCROSS to 3 and N_CYCLES to 10. Code to compute frequency double compute_frequency(struct timespec fzstamps[], int fcnt) { double f_acc = 0.0; 41 int cycles = 0, cur = 2; while (cur < fcnt) { f_acc += 1.0/time_diff(fzstamps[cur-2],fzstamps[cur]); cycles++; cur += 2; } return f_acc/cycles; } Frequency of one cycle is computed alternating timestamps as shown in line 5 of the code. Frequency is the average of frequency of all the cycles. In driver.c, it resides in the function void receive_and_process_data(int fd) 3.5.1.3 Display sub-component while (threads.process) { if (!lcdd.display) continue; lcd_send_text(&lcdd.disp, lines[cur_line % 5], 1, 0); lcd_send_text(&lcdd.disp, lines[(cur_line+1) % 5], 2, 0); lcd_send_text(&lcdd.disp, lines[(cur_line+2) % 5], 3, 0); lcd_send_text(&lcdd.disp, units[cur_line % 5], 1, 9); lcd_send_text(&lcdd.disp, units[(cur_line+1) % 5], 2, 9); lcd_send_text(&lcdd.disp, units[(cur_line+2) % 5], 3, 9); double quantities[6]; pthread_mutex_lock(&lcdd.lock); { quantities[5] = lcdd.cur_state.energy; quantities[0] = lcdd.cur_state.power; quantities[1] = lcdd.cur_state.v_rms; quantities[2] = lcdd.cur_state.a_rms; quantities[3] = lcdd.cur_state.frequency; quantities[4] = lcdd.cur_state.power_factor; samples = lcdd.cur_state.n_samples; failure = lcdd.cur_state.n_errors; lcdd.cur_state.n_samples = 0; lcdd.cur_state.n_errors = 0; lcdd.cur_state.power = 0.0; lcdd.cur_state.v_rms = 0.0; lcdd.cur_state.a_rms = 0.0; lcdd.cur_state.frequency = 0.0; lcdd.cur_state.power_factor = 0.0; } pthread_mutex_unlock(&lcdd.lock); 42 for (int i = 0; i < 6; ++i) if (fabs(quantities[i]) < 1e-4) quantities[i] = 0.0; char line0[21], line1[21], line2[21], line3[21]; printf("Samples received = %llu | %llu\n", samples,failure); sprintf(line0, sprintf(line1, sprintf(line2, sprintf(line3, "%.3f", quantities[5]); format[cur_line], quantities[cur_line]); format[(cur_line+1) % 5], quantities[(cur_line+1) % 5]); format[(cur_line+2) % 5], quantities[(cur_line+2) % 5]); lcd_send_text(&lcdd.disp, lcd_send_text(&lcdd.disp, lcd_send_text(&lcdd.disp, lcd_send_text(&lcdd.disp, line0, line1, line2, line3, 0, 1, 2, 3, 9); 9); 9); 9); cur_line = (cur_line + 1) % 5; sleep(1); } The code describes the core part of LCD sub-module which sends data to the display. pthread_mutex_lock() and pthread_mutex_unlock() are used for concurrency control since lcdd is used by other subcomponents and hence it introduces race conditions. It is important to keep the critical section (for which mutual exclusion is needed) small since LCD hardware is slow and keeping the lock for a long time delays operations in other components and hence affects the performance of the system. Then lcd_send_text() sends the text to be displayed to the LCD (See Section 3.4.2 - LCD API). The line where cur_line is incremented allows for scrolling effect in the display. sleep(1) suspends execution for 1 second. In driver.c, it resides in the function void* lcd_routine(void *d) 3.5.1.4 Communication sub-component connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); memset(sendBuff,'\0',sizeof(sendBuff)); int bytes = read(connfd, request, sizeof(request)); if (bytes < 0) { fprintf(stderr, "Failed to read client request\n"); close(connfd); Continue; } parse_request(connfd, request,sendBuff, sizeof(sendBuff)); bytes = write(connfd, sendBuff, strlen(sendBuff)+1); if (bytes < 0) { 43 fprintf(stderr, "Failed to respond\n"); } close(connfd); The code describes the process of handling requests. We have used Linux Sockets API to implement this functionality. First it accepts the client connection. Then it reads the request. The request is then parsed, that is it tries to make sense out of it. Once it is done, appropriate response is written back and the connection is closed. In driver.c, this code resides in the function void* server_comm_routine(void *data) 3.5.4. Server software Server offers a terminal to query the device. Presently, get-all command gets the RMS value of Voltage, Current, Power, Energy, Frequency, Power factor of the system at the instant of querying. Presently, the IP of the device has to be specified for establishing connection. Communication is done through the intranet. It uses TCP/IP connection. The output of the command is sent to the device as raw bytes as opposed to well formatted ones like HTTP response. It is chosen for simplicity. Right now, the request and the response are not encrypted. 3.6. Complete Circuit Diagram FIg. 3.5 44 4. Troubleshooting It is important that once the design is implemented and tested on the real time load there will be some amount of mismatch that exists between the desired results and the obtained but if it is not in a specified boundary then troubleshooting becomes necessary so there by troubleshooting of the system takes the major role in getting the desired results. Here we have got the major troubleshooting both from the software section of the project and the Hardware. 4.1. Hardware This part includes the sensor circuit, level shifter circuit, RC filter circuit and the Microcontroller circuit. The Hardware part troubleshooting becomes most crucial of the fact that the samples of current and voltage must be given accurately to the computer(Pine64) for computation, the main objective of this part is increasing S/N ratio. Since the signal level we are working with is very low (<2.5V peak-peak) that it can be easily distorted by small amount of Noise in the circuit. 4.1.1. Soldering Soldering of the components to the PCB (Printed Circuit board) created lots of problems because of high amount of wax and partially insulated leads of the components this created some resistance between nodes. 45 These are some of the Problems in nodes troubleshooted: 1. Negative supply and the voltage sensor lead 2. Positive supply node 3. Measuring terminal Node of both voltage sensor and current sensor These were the major issues troubleshooted which increased S/N ratio. Then there were many nodes which was exposed this caused the noise to get in the circuit which had major impact on S/N ratio. 4.1.2. Noise from the Level Shifter The Level shifter circuit which we have used is the opamp based and it is a laboratory based 741 IC which has its own internal component noise since it is designed in a negative feedback loop which reduced the noise at the output. Since the signal strength from the sensor is very weak this can get distorted by small amount of noise so these is a much needed filter to extract the component of frequency which we are interested (50Hz). Initially the filter circuit was designed to eliminate the frequency above 150Hz just to keep the 3 harmonics, in the initial stage of design on testing with the load from the single phase supply the 3rd harmonic was around 40% of the fundamental which was distorting the signal, we have troubleshooted this by replacing the 0.1㎌ capacitor of filter circuit with 0.22㎌ which changed the 3dB frequency from 159.15Hz to 72.34Hz so thereby eliminating the 3rd harmonics. 4.1.3. Communication Error The Arduino Uno board which was included with Atmega328P does the sampling of the signals from Voltage sensor and Current sensor and send these data according the format as in section 3.3. to the Pine64 computer through the USB 2.0. This communication uses the UART communication protocol to send the data with a specified baud rate of 230400 bits/sec when the data is received on the computer the missing of the serial identification of first two bit (identification bits for Voltage and Current data for the lower and higher byte) was found and the error constituted to around 15% at this baud rate and because of 46 this error there was lots of nonlinearity started arising in the data computed so the troubleshooting became necessary to increase the accuracy. The Arduino Uno board is replaced with the MSP430F5529LP which has an error of around -0.8% to 0% according to datasheet at the baud rate of 115200 bits/sec. This baud rate is good enough to serve our requirement with the reduction in the error which increases the linearity of the data received. Number of good samples received: Parameter Arduino Uno MSP430F5529LP Practical Theoretical Practical Theoretical Error ~15% (2 bits) linearly ~50%(8 bits) @230400 ---- -0.8% to 0% (8 bits) @115200 -0.8% to 0% @115200 Good sam/sec Around 1800 ---- 1998 to 2000 1840 to 2000 From the above table it is clear that MSP430 has a better communicating ability than Arduino and this suits well with our Project. MSP430F5529 code: #include "driverlib.h" #include "msp430.h" void adcConfigure(void); void UART_setup(void); void send_serial(int data); int conv1 (int x, short int voltage); void clock_set(void); #define MCLK_FREQ_KHZ 16000 #define FLLREF_KHZ 32 #define MCLK_FLLREF_RATIO 488 // MCLK = Master Clock (CPU) // Reference frequency FLL // Ratio used to set DCO void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop the Watchdog timer clock_set(); //initialize the MCLK = SMCLK = 16MHz and ACLK to 32768Hz int sensorValue_Voltage=0, sensorValue_Current=0; 47 adcConfigure(); UART_setup(); // Configuring ADC12_A // setting serial communication protocol UART while(1) { ADC12CTL0 &= ~ADC12SC; ADC12CTL0 |= ADC12SC + ADC12ENC; while(ADC12CTL1 & ADC12BUSY) __no_operation(); sensorValue_Voltage = ADC12MEM0&0x0FFF; sensorValue_Current = ADC12MEM1&0x0FFF; //Enabling the ADC //->P6.1 -> MEM0 //->P6.3 -> MEM1 //converting into required format and sending the data send_serial(conv1(sensorValue_Voltage,1)); send_serial(conv1(sensorValue_Current,0)); } } void adcConfigure(void) { REFCTL0 &= ~REFMSTR; //disabling the REFMSTR register ADC12CTL0 |= ADC12SHT0_9+ADC12MSC + ADC12REFON + ADC12REF2_5V + ADC12ON; ADC12CTL1 = ADC12SHP + ADC12CONSEQ_1; ADC12MCTL0 = ADC12SREF_1 + ADC12INCH_1; ADC12MCTL1 = ADC12SREF_1 + ADC12INCH_3 + ADC12EOS; P6SEL |= BIT1 + BIT3; //selecting P6.1 and P6.3 as ADC pins } void UART_setup(void) { P4SEL |= 0x30; //selecting P4.4, P4.5 as UART RX/TX pins UCA1CTL1 |= UCSWRST; //put state machine in a reset mode UCA1CTL1 |= UCSSEL_2; //selecting the clock source here its SMCLK UCA1BR0 = 138; //baudrate selection register 0 UCA1BR1 = 0x00; //baudrate selection register 1 UCA1MCTL = 0x0E; //Modulation UCA1CTL0 = 0x00; //Control register 0 UCA1CTL1 &= ~UCSWRST; //put USCI in operation mode } void send_serial(int data) { while(UCA1STAT & UCBUSY); //busy checking UCA1TXBUF = data & 0x00FF; while(UCA1STAT & UCBUSY); UCA1TXBUF = data>>8; } //function to convert the data to the required format int conv1 (int x, short int voltage) { int val = 0; int loData = x & ((1<<6)-1); int hiData = (x>>6) & ((1<<6)-1); val |= loData; val |= (hiData << 8); val |= (1<<14); if (!voltage) { 48 val |= (1<<7); val |= (1<<15); } return val; } void clock_set(void) { PMM_setVCore(PMM_CORE_LEVEL_2); //Set VCore = 2 for 16MHz UCS_initClockSignal( UCS_FLLREF, // The reference for Frequency Locked Loop UCS_REFOCLK_SELECT, // Select 32Khz reference osc UCS_CLOCK_DIVIDER_1 ); // Start the FLL and let it settle // This becomes the MCLCK and SMCLK automatically UCS_initFLLSettle( MCLK_FREQ_KHZ, MCLK_FLLREF_RATIO ); // Setting the SMCLK frequency by selection DCO source UCS_initClockSignal( UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_2 ); // Set auxiliary clock UCS_initClockSignal( UCS_ACLK, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1 ); } 4.1.4. Sampling reference The arduino Uno comes with Atmega328P microcontroller which has 1.1V internal reference which is stable and the 5V default reference which has variation in it so our requirement for this project is 2.5V max, now we have only one option to choose. I.e., 5V unstable reference. This resulted in a lots of errors while sampling the constant signal so it is taken out from the list. The arduino also supports the external reference option from Vref pin, if this option is enabled we can connect external reference so that arduino samples based on the reference. But this requires a very stable reference, we have used the 49 potential divider circuit from a 7805 ic to get a reference of 3V but this 7805 ic requires >7.5V in the input, but the battery had a very unstable voltage whose voltage drops below 7.5V after loading so this created problems in external reference. The communication issue we had in Arduino Uno is resolved by MSP430F5529 as explained in section 4.1.3. This MSP430 has 2 internal reference which are very stable 1.5V and 2.5V we have set the 2.5V reference for ADC (Analog to Digital Conversion) module which solved our issue regarding the sampling reference. Snippet of code to set 2.5V reference for ADC: REFCTL0 &= ~REFMSTR; //disabling the REFMSTR register //setting 2.5V reference ADC12CTL0 |= ADC12SHT0_9+ADC12MSC + ADC12REFON + ADC12REF2_5V + ADC12ON; ADC12CTL1 = ADC12SHP + ADC12CONSEQ_1; ADC12MCTL0 = ADC12SREF_1 + ADC12INCH_1; ADC12MCTL1 = ADC12SREF_1 + ADC12INCH_3 + ADC12EOS; P6SEL |= BIT1 + BIT3; //selecting P6.1 and P6.3 as ADC pins 4.2. Software There can be many points of failure in software. First of all, the GPIO pins might be busy and when it is the case, the application couldn’t issue commands if the other process accessing it has exclusive access to it. So the application must either wait or stop. Another component is LCD display. It is slow compared to the board computer and it might result in the command/data sent to it being missed because of insufficient delay or it might miss the pulse sent to change its state which results in it doing nothing. Then we had to work to keep the data shared between threads to be as minimal as possible. The section of code to access the shared data must be as small as possible. Otherwise might become a performance bottleneck. Serial communication settings must be done carefully. For instance, incorrect baud rate might result in the driver application seeing lots of errors in communication and hence lower accuracy. Plus, incorrect settings might lead to end of data reception which is undesirable. 50 Finally, the application has to clean up the resources like threads, sockets, file descriptors allocated to it by the system even if it is forced to terminate because of events external to the application. We have to handle signals like SIGINT, SIGKILL, SIGTERM to enforce this. 4.2.1. GPIO troubleshooting In order to work with LCD, we first have to be able to programmatically turn the GPIO pins on and off. So we executed a set of commands to test it. We tested it with LED connected to the GPIO pin. When it is high, it glows. $ # # # # sudo echo echo echo echo -i "75" > /sys/class/gpio/export "out" > /sys/class/gpio/gpio75/direction 1 > /sys/class/gpio/gpio75/value 0 > /sys/class/gpio/gpio75/value GPIO pins can be dealt with just like any other File. But it has to be registered and the direction must be set before setting the value of the pin. All this has to be done as root. Otherwise the operation fails. We wrote a small shell script which must be run at the start of the system which must be run to register all GPIO pins. CODE: exportpins.sh pins=("227" "226" "362" "71" "233" "76" "64" "65" "66" "361" "229" "230" "69" "73" "80" "32" "33" "72" "77" "78" "79" "67" "231" "360" "68" "70" "74" "75") for i in "${pins[@]}"; do echo $i > /sys/class/gpio/export Done echo 'All pins initialized' 4.2.2. LCD troubleshooting Since LCD hardware is slower compared to the board computer, it is important to add some delays in order to make the program work properly. That is what lcd_busycheck() function does in disp.c file. The LCD hardware is positive edge triggered and there must also be simulate a little pulse. static void lcd_trigger_device(LCD *disp) { lcd_set_enable(disp, LOW); nanosleep(&trigger_delay, NULL); lcd_set_enable(disp, HIGH); 51 nanosleep(&trigger_delay, NULL); lcd_set_enable(disp, LOW); } static void lcd_busycheck(LCD *disp) { nanosleep(&busycheck_delay, NULL); } Once it was done, we also needed to add some additional delay after issuing clear screen command to the display. So we added a two microsecond delay. We arrived at the figure after experimenting with it. 4.2.3. Driver troubleshooting 4.2.3.1 Splitting the work among different cores Creating a new thread doesn’t guarantee that it is running on a core which is different from that of the current thread. It depends on OS scheduler. But it is necessary for the application to do that in order to achieve high performance. OS Scheduler is not dependable. Hence we had to force it. int attach_thread_to_core(int core_id) { int max_cores = sysconf(_SC_NPROCESSORS_ONLN); if (core_id < 0 || core_id >= max_cores) return EINVAL; cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(core_id, &cpuset); pthread_t thread = pthread_self(); return pthread_setaffinity_np(thread, sizeof(cpuset), &cpuset); } This piece of code explicitly requests the scheduler to bind the current thread (the thread which called it) to bind to the specified core. This is done by the function pthread_setaffinity_np(). This solves our problem at the cost of portability of the code to a platform other than Linux. It isn’t important anyways. 4.2.3.2. Long critical section in Display module As mentioned in section 4.2.2, LCD hardware is slow and when the thread running Display component holds a mutex for a long time, it affects the performance of other components, 52 mainly Receive and process sub-component which is vital to process the data received from the sampler. LCD display has delays in terms of microseconds and milliseconds. Holding mutex for that long is unacceptable from the viewpoint of performance. quantities[5] quantities[0] quantities[1] quantities[2] quantities[3] quantities[4] = = = = = = lcdd.cur_state.energy; lcdd.cur_state.power; lcdd.cur_state.v_rms; lcdd.cur_state.a_rms; lcdd.cur_state.frequency; lcdd.cur_state.power_factor; So we copied the values we needed to display to other variables in the critical section, release the mutex and then work on displaying thereby allowing other sub-components to proceed executing their critical sections. The piece of code shown above solved the problem. 4.2.3.3. Handling blocking accept() function The driver program has to be terminated properly. Otherwise, there might be sockets used by the communication sub-component which are not closed. They cause problem when the program is run in the future. The problem is that the accept() function in Sockets API is blocking. So on interrupt, this thread doesn’t finish and hence doesn’t let the application clean up resources and terminate. The sockets have to be manually closed by issuing SIGKILL (it can be done by kill command in Linux) to stopped processes. How to solve this issue? The listening socket in the component changes when there is an incoming connection request. So we have to monitor the descriptor corresponding to the listening socket for change. Here is a piece of code that does that. int poll_status = poll(&poll_listenfd, 1, 2000); if (poll_status == -1) { perror("ERROR"); continue; } if (poll_status == 0) continue; This ensures that accept() is not reached unless there is a new incoming connection request. poll() is a Linux system call for monitoring the file descriptor. Another option was the use the libevent library for faster performance. But for our purposes, it is an overkill and makes the application bigger and adds a dependency. 53 4.2.3.4 Serial communication settings Earlier we mentioned that communication through serial port is just like File I/O because of “everything is a file” philosophy. But how does the system know the settings like baud rate? The solution is the termios structure. int set_tty_attributes(int fd) { struct termios options; tcgetattr(fd, &options); cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); options.c_cflag options.c_cflag options.c_cflag options.c_cflag options.c_cflag |= &= &= &= |= (CLOCAL | CREAD); ~CSTOPB; ~CRTSCTS; ~CSIZE; CS8; options.c_iflag |= IGNBRK; options.c_iflag &= ~(BRKINT|IMAXBEL|IXON); options.c_oflag &= ~(OPOST|ONLCR); options.c_lflag &= ~(ICANON|IEXTEN|ECHO|ECHOE); options.c_lflag &= ~(ECHOK|ECHOCTL|ECHOKE|NOFLSH); options.c_cc[VMIN] = 1; options.c_cc[VTIME] = 10; return tcsetattr(fd,TCSANOW,&options); } This piece of code solves the problem. In this case baud rate is set to 115200. In case there is any problem in serial communication this is the place to look. Some of it is standard UART settings. 4.2.3.5 Detecting valid zero crossings Detecting zero crossing is easy because we have access to the current value and the previous value. But there are transmission errors and we might miss some zero crossings. So we have to detect if there are any zero crossings which are missing because they affect the accuracy of frequency, power factor and energy computation a lot. 54 const double ZCROSS_DELTA_MIN = <MIN-TIME BETWEEN ZERO CROSSINGS>; const double ZCROSS_DELTA_MAX = <MAX-TIME BETWEEN ZERO CROSSINGS>; inline bool is_valid_zero_crossing(struct timespec prev, struct timespec cur) { return time_diff(prev,cur) >= ZCROSS_DELTA_MIN && time_diff(prev,cur) <= ZCROSS_DELTA_MAX; } This piece of code solves the problem. Since we have the rough idea of frequency, we can compute the time between zero crossings roughly assuming some error margin in frequency which is represented by the constants ZCROSS_DELTA_MIN and ZCROSS_DELTA_MAX. Setting ZCROSS_DELTA_MIN to high or ZCROSS_DELTA_MAX to lower value might lead to many valid zero crossings to be flagged invalid and hence it must be set carefully. It is set experimentally starting with very low ZCROSS_DELTA_MIN and very high ZCROSS_DELTA_MAX and narrowing down the range of values for better accuracy. But it is not the only parameter affecting accuracy of computations. 4.3. Final Circuit Diagram Fig. 4.3 55 5. Results The Final circuit Diagram is tested and the results obtained are tabulated. The output from each and every section of the circuit is taken and analysed to check if the required conditions on the accuracy is met to put the meter on use. The results below are shown for different loading conditions so the values will not match. 5.1. Sensor Output This section gives the results from the sensors, these results are captured by a DSO (Digital Storage Oscilloscope) and the results are verified with the expected results. Voltage sensor: Fig. 5.1.1 The voltage applied is 95V (single phase 50Hz) Voltage sensor conversion constant is 398 (as measured in section 3.1.3.1) Voltage (rms) 56 Expected Result Obtained Result 95/398 = 0.2387 340/1000/20.5 = 0.2404 Current sensor: Fig. 5.1.2 Current drawn by the load is 10.1A Current sensor constant is 46 (measured in section 3.1.3.2) Voltage (rms) Expected Result Obtained result 10.1/46 = 0.2196 320/1000/20.5 = 0.2263 5.2. Level shifter with filter output This circuit gives a rise to the sensor voltage with the filtering action, the filter will not allow any frequency above 72Hz, so only the fundamental frequency of the voltage/current is obtained which makes the computations noise free and easy algorithm to make computations. 57 Voltage signal (yellow)l: Fig. 5.2.1 Current signal (green): FIg. 5.2.2 We can see from the above figures that the Vavg = 1.20V, and our expected is 1.25V but it is close enough for the algorithm to detect the zero crossings. 58 5.3. LCD Display output This displays the values of the parameters computed using the voltage and current data locally in the LCD display. Parameters that are displayed: 1. Energy in KWh 2. Power in KW 3. Voltage in Volt (V) 4. Current in Ampere (A) 5. Power factor 6. Frequency (Hz) Fig. 5.3 59 5.4. Remote Device output The results which are displayed locally can be communicated to the remote device with TCP/IP protocol. Here we have connected the Meter to the NITK-NET through its wifi module and the remote receiver is also connected to the NITK-NET, the data is received by the remote receiver after a command called ‘get_all(1)’ is sent. Fig. 5.4 5.5. Conclusion The results obtained has a satisfactory outcome even though the error is not within the standard limits but it is still a good enough outcome in the laboratory level. The Section 6 of this report gives a brief idea about the future improvements that has to be included so as to get the errors under the limits and meet the standard. This design used for this Smart meter design is good enough for the residential energy measurement because there are nothing about the harmonics involved in this circuit is mentioned and the range of its operation is also limited to 250V which is a single phase. 60 6. Future improvements This will help the project to get its next step of improvement both in Hardware and software to meet the desired standards and used in real time metering of the residential or any single phase energy reading with automated billing for the consumed energy and also the alert in the remote device about the consumption. 6.1. Hardware 1. The grade of the components used must be increased to get a better reliability of the circuit and it also makes the circuit less sensitive to external environment.The noise levels of the components majorly 741 IC is reduced. 2. The filter circuit must be replaced with the Narrow bandpass filter (40Hz-60Hz) so that the lower frequency noise will be eliminated, it is recommended to use the Active filter so that the signal strength can be increased or maintained at the same level. 3. The quality of the printed circuit board must be good which reduces the noise levels of the circuit. 4. The hard wiring must be firmly soldered to avoid any resistance in the nodes. 5. The sensors could be added with more protection just to make sure that the measuring quantities are within the limits if not stop measuring and give a alert to say that quantity is above the rating. 6. The cable length of communication between MSP430 and Pine64 must be reduced to increase the transmission accuracy at higher bitrates. 7. The reference generator which is a 7805 IC with a potential divider circuit and voltage output from this entirely depends on the battery potential and the loading on the circuit, this could be replaced with a DC-DC converter based on frequency control with automatically controls the output voltage at a constant level (1.25V). And this stable reference is much more necessary. 61 6.2. Software 1. Improvements in recording zero crossing detection timestamp. It has to be done accurately using techniques like interpolation. 2. Improvements in error handling using signal processing techniques (adaptive filters etc). Guessing the values of missing samples using interpolation techniques help to improve the accuracy of various quantities computed. 3. More commands can be supported from the device. 4. Creation of a central database to gather data from various smart meter devices for further analysis and better decision making. 5. Adding security features to the device to avoid tampering. 6. A graphical frontend on the server end for people in the company. Dashboard and other visualizations help them to get a picture of the system easily. 7. A frontend for users - either a website or a smartphone application which allows them to view the usage the power consumption at the moment, helps them to pay bills online, submit query to the company and so on. 8. A rich data repository for data analysts to slice and dice data based on the consumption and optimize the power supply and quality based on it. 62 7. Application(s) The Smart Energy Meters are the revolution in the field of Automation, this gets everything in the palm, with a user friendly interface to manage the energy consumption remotely. 7.1. Automatic Billing Fig. 7.1 The data that is measured by the smart meter is sent to the remote server through a gateway where it takes the account of the energy readings and puts it to the database then this information is used for the billing on monthly basis. 7.2. Alerting system The Smart Meter can alert the user about the Energy usage, the maximum power consumption in a day or the tripping of the circuit breaker because of some fault in the load side and these can be easily communicated with the remote device and give an alert on the current situation. 63 8. References 1. Ramakanth A. Gayakwad “Op-Amps and Linear Integrated Circuits - 4th Edition” 2. “www.circuitbasics.com”- About Universal Asynchronous Receiver transmitter 3. “www.ti.com”- Documentations related to MSP430F5529LP Programming 4. Pthread tutorial - https://computing.llnl.gov/tutorials/pthreads 5. Pthread documentation - http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html 6. C sockets documentation https://www.gnu.org/software/libc/manual/html_node/Sockets.html 7. poll() documentation - http://man7.org/linux/man-pages/man2/poll.2.html 8. “www.arduino.cc” - Documentations related to Arduino Uno Programming 64