Skip to the content.

MycilaJSY

Latest Release PlatformIO Registry

License: MIT Contributor Covenant

Build GitHub latest commit Gitpod Ready-to-Code

Arduino / ESP32 library for the JSY1031, JSY-MK-163, JSY-MK-193, JSY-MK-194, JSY-MK-227, JSY-MK-229, JSY-MK-333 families single-phase and three-phase AC bidirectional meters from Shenzhen Jiansiyan Technologies Co, Ltd.

API Documentation

Go to: https://mathieu.carbou.me/MycilaJSY/api/index.html

Features

Also read the blog article: Everything on le JSY

Supported models

JSY1031 (TTL)

JSY-MK-163T (TTL)

JSY-MK-193 (RS485)

For each channel (1 and 2):

JSY-MK-194T (TTL) and JSY-MK-194G (TTL)

For each channel (1 and 2):

JSY-MK-227 (RS485) and JSY-MK-229 (RS485)

JSY-MK-333 (TTL) and JSY-MK-333G (RS485)

For each phase (A, B and C):

Usage

PIO file:

Make sure to use that in your platformio.ini:

; Arduino 3.0.x
; platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip
; Arduino 3.1.x
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip

build_flags =
  -std=c++17
  -std=gnu++17
  -Wall -Wextra

build_unflags =
    -std=gnu++11
  1. make sure to use pioarduino platform because PlatformIO provided platforms are not compatible with Arduino Core 3.
  2. C++ 17 is required for mutex

Arduino IDE also has a place to set compilation flags.

Sample code:

#include <MycilaJSY.h>

Mycila::JSY jsy;

void setup() {
  jsy.begin(Serial2, RX2, TX2);
}

void loop() {
  if (jsy.read()) {
    float v = jsy.data.single().voltage; // for JSY1031, JSY-163, JSY-227, JSY-229

    float v1 = jsy.data.channel1().voltage; // for JSY-193 and JSY-194
    float v2 = jsy.data.channel2().voltage; // for JSY-193 and JSY-194

    float vA = jsy.data.phaseA().voltage; // for JSY-333
    float vB = jsy.data.phaseB().voltage; // for JSY-333
    float vC = jsy.data.phaseC().voltage; // for JSY-333
    float p = jsy.data.aggregate().activePower; // for JSY-333
  }
  delay(4000);
}

Baud rate detection / forcing a baud rate

// by default, will try to detect the baud rate
jsy.begin(Serial2, RX2, TX2, Mycila::JSY::BaudRate::UNKNOWN);

// Skips baud rate detection and use the given baud rate
jsy.begin(Serial2, RX2, TX2, Mycila::JSY::BaudRate::BAUD_38400);

Destination Address

// by default, will send to any device (broadcast)
jsy.begin(Serial2, RX2, TX2, Mycila::JSY::BaudRate::UNKNOWN, MYCILA_JSY_ADDRESS_BROADCAST);

// Use the given address
jsy.begin(Serial2, RX2, TX2, Mycila::JSY::BaudRate::UNKNOWN, 0x01);

Model detection / forcing a model

// by default, will try to detect the model
jsy.begin(Serial2, RX2, TX2, Mycila::JSY::BaudRate::UNKNOWN, MYCILA_JSY_ADDRESS_BROADCAST, MYCILA_JSY_MK_UNKNOWN);

// Skips model detection and use the given model
jsy.begin(Serial2, RX2, TX2, Mycila::JSY::BaudRate::UNKNOWN, MYCILA_JSY_MK_227, MYCILA_JSY_MK_194);

Blocking mode

Mycila::JSY jsy;

void setup() {
  jsy.begin(Serial2, RX2, TX2);
}

void loop() {
  jsy.read();

  // access values
  float v = jsy.data.single().voltage;

  delay(1000);
}

Non-Blocking mode (async)

Mycila::JSY jsy;

void setup() {
  jsy.begin(Serial2, RX2, TX2, true);
}

void loop() {
  // access values
  float v = jsy.data.single().voltage;
}

Energy reset

jsy.resetEnergy();

Update Baud rate (change speed)

jsy.setBaudRate(Mycila::JSY::BaudRate::BAUD_38400);

Change device address

jsy.setDeviceAddress(0x02);

Switch AC/DC mode

Only for JSY1031:

jsy.setMode(Mycila::JSY::Mode::DC);

JSON Support

You can activate JSON support by defining -D MYCILA_JSON_SUPPORT in your project and add the ArduinoJson library.

Debugging

Set the flag: -D MYCILA_JSY_DEBUG and you will see all the JSY requests and responses.

Callbacks

Example:

Reading a load for 2 second after it is turned on:

  jsy.setCallback([](const Mycila::JSY::EventType eventType) {
    int64_t now = esp_timer_get_time();
    switch (eventType) {
      case Mycila::JSY::EventType::EVT_READ:
        Serial.printf(" - %" PRId64 " EVT_READ\n", now);
        break;
      case Mycila::JSY::EventType::EVT_CHANGE:
        Serial.printf(" - %" PRId64 " EVT_CHANGE: %f W\n", now, jsy.getActivePower2());
        break;
      default:
        Serial.printf(" - %" PRId64 " ERR\n", now);
        break;
    }
  });

Output example:

jsy.read() at 4800 bauds:
 - 4406487 EVT_READ
 - 4406577 EVT_CHANGE: 0.000000 W
 - 4576361 EVT_READ
 - 4576452 EVT_CHANGE: 0.567600 W
 - 4746390 EVT_READ
 - 4918004 EVT_READ
 - 4918078 EVT_CHANGE: 238.452896 W
 - 5088016 EVT_READ
 - 5257985 EVT_READ
 - 5258059 EVT_CHANGE: 501.204590 W
 - 5428006 EVT_READ
 - 5597980 EVT_READ
 - 5598055 EVT_CHANGE: 509.064789 W
 - 5767989 EVT_READ
 - 5937958 EVT_READ
 - 5938032 EVT_CHANGE: 507.976410 W
 - 6107979 EVT_READ
 - 6279620 EVT_READ
 - 6279694 EVT_CHANGE: 507.588196 W

jsy.read() at 9600 bauds:
 - 7266640 EVT_READ
 - 7266727 EVT_CHANGE: 21.132200 W
 - 7366557 EVT_READ
 - 7474854 EVT_READ
 - 7474928 EVT_CHANGE: 0.847700 W
 - 7577383 EVT_READ
 - 7677342 EVT_READ
 - 7777330 EVT_READ
 - 7877334 EVT_READ
 - 7877408 EVT_CHANGE: 497.609192 W
 - 7977363 EVT_READ
 - 8077326 EVT_READ
 - 8177318 EVT_READ
 - 8177392 EVT_CHANGE: 506.894501 W
 - 8277345 EVT_READ
 - 8377319 EVT_READ
 - 8478147 EVT_READ
 - 8478222 EVT_CHANGE: 506.710205 W
 - 8578164 EVT_READ
 - 8678138 EVT_READ
 - 8778135 EVT_READ
 - 8878132 EVT_READ
 - 8878207 EVT_CHANGE: 506.827393 W
 - 8978150 EVT_READ
 - 9078122 EVT_READ
 - 9178953 EVT_READ
 - 9179027 EVT_CHANGE: 506.932892 W

jsy.read() at 19200 bauds:
 - 9820293 EVT_READ
 - 9820383 EVT_CHANGE: 269.228302 W
 - 9880195 EVT_READ
 - 9940570 EVT_READ
 - 10000562 EVT_READ
 - 10060548 EVT_READ
 - 10120538 EVT_READ
 - 10120613 EVT_CHANGE: 19.392099 W
 - 10180976 EVT_READ
 - 10240944 EVT_READ
 - 10300926 EVT_READ
 - 10360912 EVT_READ
 - 10421327 EVT_READ
 - 10421402 EVT_CHANGE: 287.241699 W
 - 10481350 EVT_READ
 - 10541308 EVT_READ
 - 10601290 EVT_READ
 - 10661285 EVT_READ
 - 10721280 EVT_READ
 - 10781686 EVT_READ
 - 10781769 EVT_CHANGE: 506.096008 W
 - 10841700 EVT_READ
 - 10901667 EVT_READ
 - 10961658 EVT_READ
 - 11022060 EVT_READ
 - 11082050 EVT_READ
 - 11082125 EVT_CHANGE: 505.992493 W
 - 11142072 EVT_READ
 - 11202031 EVT_READ
 - 11262031 EVT_READ
 - 11322425 EVT_READ
 - 11382419 EVT_READ
 - 11442409 EVT_READ
 - 11442484 EVT_CHANGE: 505.818298 W
 - 11502441 EVT_READ
 - 11562390 EVT_READ
 - 11622804 EVT_READ
 - 11682791 EVT_READ
 - 11742799 EVT_READ
 - 11742874 EVT_CHANGE: 505.483002 W
 - 11802804 EVT_READ

jsy.read() at 38400 bauds:
 - 13017424 EVT_READ
 - 13017515 EVT_CHANGE: 11.180500 W
 - 13067332 EVT_READ
 - 13067423 EVT_CHANGE: 0.000000 W
 - 13117320 EVT_READ
 - 13157496 EVT_READ
 - 13207482 EVT_READ
 - 13247472 EVT_READ
 - 13287678 EVT_READ
 - 13337675 EVT_READ
 - 13377664 EVT_READ
 - 13417866 EVT_READ
 - 13417941 EVT_CHANGE: 320.179688 W
 - 13467890 EVT_READ
 - 13517859 EVT_READ
 - 13557844 EVT_READ
 - 13598042 EVT_READ
 - 13648037 EVT_READ
 - 13688036 EVT_READ
 - 13728237 EVT_READ
 - 13728312 EVT_CHANGE: 503.697113 W
 - 13778253 EVT_READ
 - 13828221 EVT_READ
 - 13868215 EVT_READ
 - 13908412 EVT_READ
 - 13958400 EVT_READ
 - 13998398 EVT_READ
 - 14046098 EVT_READ
 - 14046173 EVT_CHANGE: 507.100891 W
 - 14088424 EVT_READ
 - 14128377 EVT_READ
 - 14168579 EVT_READ
 - 14208568 EVT_READ
 - 14248575 EVT_READ
 - 14288771 EVT_READ
 - 14328769 EVT_READ
 - 14376462 EVT_READ
 - 14376537 EVT_CHANGE: 507.294708 W
 - 14418996 EVT_READ
 - 14468947 EVT_READ
 - 14508941 EVT_READ
 - 14548930 EVT_READ
 - 14589151 EVT_READ
 - 14629129 EVT_READ
 - 14669129 EVT_READ
 - 14709325 EVT_READ
 - 14709400 EVT_CHANGE: 507.153198 W
 - 14759359 EVT_READ
 - 14799311 EVT_READ
 - 14839513 EVT_READ
 - 14889501 EVT_READ
 - 14929499 EVT_READ
 - 14969706 EVT_READ

Remote JSY

The JSY can be used connected to an ESP32 to send the JSY data several times per second to a remote server through UDP. Both devices needs to be connected to the same network and UDP packets must be allowed.

Screenshot of the ESP32 running the JSY app called the Sender:

Click here for the download and installation instructions of the JSY Remote UDP Sender

Zero-Cross Detection

The JSY-MK-194G has a zero-cross detection feature which signals on the Zx pin when the current crosses zero. This feature is really useful to create Solr Routers like YaSolR.

The MycilaPulseAnalyzer library supports many ZC detection methods including the JSY-MK-194G.

Boxes and 3D models

You can make (print) a box or buy one, and then append a SSR Din Rail clip at the bottom:

Cases for the JSY-MK-194 T

Cases for the JSY-MK-194 G

Here is the STL file I use for the JSY-MK-194G box mounted on a DIN rail: JSY-MK-194G.stl which was created thanks to this parametric model with these parameters:

ShowBottom                = true;
ShowTop                   = true;
DistanceBetweenObjects    = 10;
ShowCaseAssembled         = false;

Caselength                = 90;
CaseWidth                 = 60;
CaseHeight                = 42;

BottomTopThickness        = 2.0;

CountersinkScrew          = 3.0;

ShowDeviceHolder         = true;
ScrewHoleDiameter        = 2.6;
ScrewCylinderDiameter    = 7;
ScrewCylinderHeight      = 7.0;
DeviceHolder_X_Distance  = 58;
DeviceHolder_y_Distance  = 42;
Offset_X                 = 0;
Offset_Y                 = 0;
ShowSideWallHoles        = true;
SideWallHolesOn_X        = false;
CountOfSideWallHoles     = 2;
SideWallHoleDiameter     = 20;
SiedWallHoleOffset_Z     = 0;

Performance tests

Here are below some test results for the JSY at different baud rates for 50 consecutive reads on a nominal load of about 650W, controlled with a random SSR relay (0-100%).

You can run the PerfTests from the examples.

PerfTest1

jsy.read() at 4800 bauds:
 - Errors: 0
 - Average read time: 170583 us
 - Min read time: 168330 us
 - Max read time: 178322 us

jsy.read() at 9600 bauds:
 - Errors: 0
 - Average read time: 100525 us
 - Min read time: 99897 us
 - Max read time: 108333 us

jsy.read() at 19200 bauds:
 - Errors: 0
 - Average read time: 60078 us
 - Min read time: 59568 us
 - Max read time: 60413 us

jsy.read() at 38400 bauds:
 - Errors: 0
 - Average read time: 41248 us
 - Min read time: 39894 us
 - Max read time: 49936 us

PerfTest2

jsy.read() at 4800 bauds:
 - ROUND: 1
   * Load Detection time: 169670 us (1 reads)
   * Ramp up time: 347890 us (2 reads)
   * Ramp down time: 1363108 us (8 reads)
 - ROUND: 2
   * Load Detection time: 679860 us (4 reads)
   * Ramp up time: 1191511 us (7 reads)
   * Ramp down time: 1531476 us (9 reads)
 - ROUND: 3
   * Load Detection time: 679867 us (4 reads)
   * Ramp up time: 1198192 us (7 reads)
   * Ramp down time: 1363164 us (8 reads)
 - ROUND: 4
   * Load Detection time: 681522 us (4 reads)
   * Ramp up time: 1191498 us (7 reads)
   * Ramp down time: 1531493 us (9 reads)

jsy.read() at 9600 bauds:
 - ROUND: 1
   * Load Detection time: 299799 us (3 reads)
   * Ramp up time: 1100600 us (11 reads)
   * Ramp down time: 1501484 us (15 reads)
 - ROUND: 2
   * Load Detection time: 700694 us (7 reads)
   * Ramp up time: 1101510 us (11 reads)
   * Ramp down time: 1501474 us (15 reads)
 - ROUND: 3
   * Load Detection time: 400709 us (4 reads)
   * Ramp up time: 800693 us (8 reads)
   * Ramp down time: 1201502 us (12 reads)
 - ROUND: 4
   * Load Detection time: 700710 us (7 reads)
   * Ramp up time: 800693 us (8 reads)
   * Ramp down time: 1200678 us (12 reads)

jsy.read() at 19200 bauds:
 - ROUND: 1
   * Load Detection time: 362264 us (6 reads)
   * Ramp up time: 1082982 us (18 reads)
   * Ramp down time: 1261343 us (21 reads)
 - ROUND: 2
   * Load Detection time: 300247 us (5 reads)
   * Ramp up time: 1020957 us (17 reads)
   * Ramp down time: 1261351 us (21 reads)
 - ROUND: 3
   * Load Detection time: 360253 us (6 reads)
   * Ramp up time: 1081379 us (18 reads)
   * Ramp down time: 1260926 us (21 reads)
 - ROUND: 4
   * Load Detection time: 300273 us (5 reads)
   * Ramp up time: 1020982 us (17 reads)
   * Ramp down time: 1261351 us (21 reads)

jsy.read() at 38400 bauds:
 - ROUND: 1
   * Load Detection time: 468076 us (11 reads)
   * Ramp up time: 840729 us (20 reads)
   * Ramp down time: 1291332 us (32 reads)
 - ROUND: 2
   * Load Detection time: 330244 us (8 reads)
   * Ramp up time: 1020971 us (25 reads)
   * Ramp down time: 1281353 us (32 reads)
 - ROUND: 3
   * Load Detection time: 330047 us (8 reads)
   * Ramp up time: 1030773 us (25 reads)
   * Ramp down time: 1301323 us (32 reads)
 - ROUND: 4
   * Load Detection time: 330047 us (8 reads)
   * Ramp up time: 1010776 us (25 reads)
   * Ramp down time: 1281343 us (32 reads)

The “Load Detection time” is the time it takes for the JSY to see a load > 0 just after the relay was closed on a constant resistive load.

The “Ramp up time” is the time it takes for the JSY to stabilize (with a maximum delta of 1% from last measurement) and see an expected load value.

The “Ramp down time” is the time it takes for the JSY to return to 0W after the relay was opened.

What these results mean ?

Reference material