R&D Experiments

A DIY Charging Point for an Electric Car: Perspective, Protocol & Prototype

8 min read

Article image

It’s no secret that the Earth is running out of fossil fuels, so increasingly more people are hurrying to find alternative sources of energy and ways to produce them. Driving electric vehicles could be one of the solutions to reduce the use of fossil fuels and also mitigate another issue - the amount of CO2 emissions.

But if electric cars are so useful, why isn’t everyone driving them yet? Two words: price and charging. Electric vehicles (EV) are too expensive for the mass market, and finding a decent charging station is no piece of cake. And while we cannot do anything about the first problem, ElifTech can help you build a charging point at home.


The Full Guide to Building a DIY Charging Point for Electric Cars

Yes, the price is one of the major factors preventing electric car use from being widespread. A regular EV like a Nissan Leaf can cost as much as a top-trim family sedan or an SUV. The price of an electric car largely depends on the battery. Big “fuel tanks” cost a lot, but the bigger the battery, the longer your EV can go on a single charge. So, do battery-powered vehicles have a bright future if not everyone can afford them?

Take a look at these statistics.

EV battery statistics

As you can see the price of batteries (per kilowatt) has dropped more than 50%, and their capacity has more than tripled in the last five years. This trend seems to continue, especially when you look at countries like the Netherlands that have promised to give up petrol engines completely by 2025-35.

Car batteries

Open Charge Point Protocol

With the rapid development of electric vehicles, charging stations have also evolved. You can find at least a couple of public EV charging stations in big cities. They typically require no maintenance staff or cashiers and take up little space.

Fuel station
Charging stations presented at the Plug-in Ukraine exhibition, March 2-4, 2018
Charging Stations Presented at the Plug-in Ukraine Exhibition, March 2-4, 2018

You can usually buy electricity for your vehicle using a specific mobile application. It will activate the power outlet that will charge your electric car. But how does the power outlet know when and which electric vehicle to charge?

Open network communication

Because the number of charging station constructors and supervision system suppliers had grown, there was a critical need for a standard communication protocol. The Open Charge Alliance (OCA) has decided to develop a standard communication protocol titled Open Charge Point Protocol (OCPP). It will allow different users to have a standard communication protocol and interconnect their systems.

How Does OCPP Work?

Before we find out how OCPP works, let’s take a look at the key components.

  • Central system — a charge point management system that manages charging stations and authorizes users.
  • Charge point — a physical charging station with one or more connectors.
  • Connector — an independently operated and managed electrical outlet on a charge point. Usually, this is a single physical connector, but sometimes a single outlet may have various physical socket types and tethered cable/connector arrangements.

So, the central system controls all charge points. When switched on/off, or if any parameters are changed, the points transmit information to the center. A car owner sends a signal to the center through the mobile app to activate one of the charging stations. That’s how the central system transmits user commands to the charge point.

Currently, protocol versions 1.0, 1.5 and 1.6 are available, while 2.0 is still in the draft stage. Versions 1.x support two data formats: SOAP and JSON. Depending on the format, you can find either OCPP-1.x-S or OCPP-1.x-J respectively. The Version 1.6 of the OCPP protocol consists of 28 operations, 10 of which are initiated by the charging station and 18 by the central system. You can find all these commands in the documentation.

The OCPP Version 2.0 will only support the JSON format. SOAP uses XML for data transmission and is too redundant. This is critical since filling stations connect to the Internet via mobile providers.

DIY Charging Point

As engineers and researchers, we wanted to try and create a DIY charging point for an electric car.

Writing a Test Protocol

First, we needed to write a test protocol before the testing phase. We need to do this to define which actions to test and which OCPP messages to expect after each of these actions occurs. This would allow us to see how a full-scale charging station can interact with the end user.

Actions

  • Start a charging session. Start a charging session from the web-based user interface (UI).

Expected OCPP messages:

  • RemoteStartTransaction
  • StatusNotification —> Occupied
  • StartTransaction
  • MeterValues
  • Stop a charging session. Stop a charging session from the web UI.

Expected OCPP messages:

  • RemoteStopTransaction
  • StopTransaction
  • StatusNotification —> Available
      
        // https://github.com/elifTech/cpd-ocpp/blob/pi/examples/centralSystem.js
        cSystem.onRequest = async function (client, command) {
          const connection = client.connection;
      
          console.info(`New command from ${connection.url}`);
      
          switch (true) {
            case command instanceof OCPPCommands.BootNotification:
              client.info = {
                connectors: [],
                ...command
              };
              return {
                status: BootNotificationConst.STATUS_ACCEPTED,
                currentTime: new Date().toISOString(),
                interval: 60
              };
      
            case command instanceof OCPPCommands.Authorize:
              return {
                idTagInfo: {
                  status: AuthorizeConst.STATUS_ACCEPTED
                }
              };
      
            case command instanceof OCPPCommands.StartTransaction:
              return {
                transactionId: 1,
                idTagInfo: {
                  status: StartTransactionConst.STATUS_ACCEPTED
                }
              };
      
            case command instanceof OCPPCommands.StopTransaction:
              return {
                transactionId: 1,
                idTagInfo: {
                  status: StartTransactionConst.STATUS_ACCEPTED
                }
              };
      
            case command instanceof OCPPCommands.Heartbeat:
              return {
                currentTime: new Date().toISOString()
              };
      
            case command instanceof OCPPCommands.StatusNotification:
              const connectorIndex = client.info.connectors.findIndex(item => command.connectorId === item.connectorId);
              if (connectorIndex === -1) {
                client.info.connectors.push({
                  ...command
                });
              } else {
                client.info.connectors[connectorIndex] = {
                  ...command
                };
              }
              await cSystem.onStatusUpdate();
              return {};
            default:
              throw new OCPPError(ERROR_NOTIMPLEMENTED, 'Unknown command');
          }
        };
      
        cSystem.toggleChargePoint = async (client, connectorId) => {
          const connector = client.info.connectors.find(item => connectorId.toString() === item.connectorId.toString());
          if (!connector) {
            return null;
          }
      
          if (connector.status !== StatusNotificationConst.STATUS_AVAILABLE) {
            let command = new OCPPCommands.RemoteStopTransaction({
              transactionId: connectorId
            });
            await client.connection.send(command);
            return;
          }
      
          let command = new OCPPCommands.RemoteStartTransaction({
            connectorId: connectorId,
            idTag: '' + connectorId
          });
      
          await client.connection.send(command);
        };
      
      
        // https://github.com/elifTech/cpd-ocpp/blob/pi/examples/chargingPoint.js
        const client = new ChargePoint({
          centralSystemUrl: `https://ocpp-example.herokuapp.com/webServices/ocpp/CP${Math.floor(Math.random() * 9999)}`,
          connectors: [
            connector1,
            connector2
          ]
        });
      
        try {
          await client.connect();
      
          client.onRequest = async (command) => {
            switch (true) {
              case command instanceof OCPPCommands.RemoteStartTransaction:
                setTimeout(() => startTransaction(command), 1);
                return {
                  status: RemoteStartTransactionConst.STATUS_ACCEPTED
                };
              case command instanceof OCPPCommands.RemoteStopTransaction:
                setTimeout(() => stopTransaction(command), 1);
                return {
                  status: RemoteStartTransactionConst.STATUS_ACCEPTED
                };
            }
          };
      
          const boot = new OCPPCommands.BootNotification({
            chargePointVendor: 'BrandX',
            chargeBoxSerialNumber: 'SR' + Math.round(Math.random() * 100000),
            chargePointSerialNumber: '123',
            chargePointModel: '12'
          });
      
          let answer = await client.send(boot);
      
          await client.sendCurrentStatus();
        } catch (err) {
          console.error('--- Err', err);
        }
      
        async function startTransaction({ connectorId }) {
          const idTag = 'test';
          const authCommand = new OCPPCommands.Authorize({
            idTag
          });
      
          await client.send(authCommand);
      
          const statusCommand = new OCPPCommands.StatusNotification({
            connectorId,
            errorCode: StatusNotificationConst.ERRORCODE_NOERROR,
            status: StatusNotificationConst.STATUS_CHARGING
          });
      
          await client.send(statusCommand);
      
          const startCommand = new OCPPCommands.StartTransaction({
            connectorId,
            idTag,
            meterStart: 0,
            timestamp: new Date().toISOString(),
          });
      
          await client.send(startCommand);
      
          connectorId === 1 ? pin17.reset() : pin27.reset();
        }
      
        async function stopTransaction({ transactionId }) {
          const statusCommand = new OCPPCommands.StatusNotification({
            connectorId: transactionId,
            errorCode: StatusNotificationConst.ERRORCODE_NOERROR,
            status: StatusNotificationConst.STATUS_AVAILABLE
          });
      
          await client.send(statusCommand);
      
          const startCommand = new OCPPCommands.StopTransaction({
            transactionId,
            meterStop: 1,
            timestamp: new Date().toISOString(),
          });
      
          await client.send(startCommand);
      
          transactionId === 1 ? pin17.set() : pin27.set();
        }
      
Example of web user interface
Example of Web User Interface
Existing commercial EV charging station
Existing Commercial EV Charging Station

Designing Proper Hardware

After implementing these commands and creating the web UI, we build the hardware for our DIY charging point. We’ve built this prototype from simple components, so you can easily build it yourself.

EV Charger Prototype Components
EV Charger Prototype Components

To build a charging point prototype, you’ll need the following components:

  • A nice industrial-looking box of your taste

industrial-looking box
  • A couple of sockets (we use the common EU type)

socket
Raspberry PI 3
  • Relay module (we use two channels; the extra channels will be handy for future enhancements)

Relay module
  • Power supply (a generic one with a 5V 2A output will be just fine)

Power supply
Wires and connectors

No soldering required :)

no soldering

Now, let’s join all the components into the right model. First things first — draw a simplified scheme of your product:

simplified product scheme

Next, attach the relay module to Raspberry PI 3 using a built-in GPIO port. We will connect Raspberry 3.3V, GPIO 17, and GPIO 27 and ground them according to the diagram. Keep in mind that your relay module should support 3.3V level triggering (the Raspberry port will not trigger 12V actuated models).

Check the Raspberry PI GPIO layout below to locate the GPIO17 and GPIO27 pins.

Raspberry PI GPIO

Power up your Raspberry PI and verify the relay module:

  1. Login to Raspberry using the SSH command: ssh pi@192.168.1.126
  2. Use the built-in gpio command line app to enable the pin:gpio -g mode 17 outgpio -g mode 27 out
  3. Use the gpio command line app to turn on/off the relay channels:gpio -g write 17 0gpio -g write 17 1

Mount the external charging sockets, a power cord, and internals using screws, thermal glue, and good zip ties.

EV Charger prototype components

Now, let’s make some power wire connections. The most convenient way to do this is using the WAGO conductors. We also recommend crimping the wire with proper connectors. The wiring should look like this:

EV components, prototype
EV prototype wiring

Make sure to test the wiring before powering the high-voltage part. We recommend you do it with a multimeter and replace the 220V with a low-voltage supply (like a 1.5V or a 12V DC battery).

EV Charger Prototype

Now, you are ready to install the software and set up your personal EV car charging station!

EV charging point prototype

Conclusion

People all over the world are taking baby steps to popularize electric vehicles. Bloomberg New Energy Finance estimates that, by 2040, electric cars will make up as much as 35% of global new car sales. Yes, EVs are expensive, but having a battery-powered car is not as troublesome as you might think. You can see for yourself that it’s absolutely possible to build an electric car charging station at home. Go ahead and try it!

Share your software needs with us

Full Name*
Email*
About project*

Budget in USD

By submitting this form I agree with the Privacy Policy

What happens after you get in touch?

  • Intro call

    During a 30-minute meeting, our domain expert dives into your business and describes the steps for future collaboration.

  • Free discovery workshop

    Together with you, we clarify the requirements and define the user flow, feature list, and project risks. After that, we set up an engagement process to make your journey smooth.

  • Project planning

    Based on the info gathered and your business objectives, we provide the implementation plan, timelines and estimations for your project.