1. /*
  2.  * Author: Niklas Menke <www.niklas-menke.de>
  3.  *
  4.  * Project: power analyser
  5.  * Description: This project represent electrical parameters from a multifunction power analyser on a website.
  6.  * The electrical parameters are recorded by a Janitza UMG96S multifunction power analyser.
  7.  * An Arduino queries the data via MODBUS RTU and sends it to a database.
  8.  * The website loads the parameters from the database and updates itself automatically via AJAX.
  9.  *
  10.  * File: powerAnalyser.ino
  11.  * Description: Get the electrical parameters from the Janitza UMG96S with MODBUS RTU and send it to the server.
  12.  * Date: 2020/07/09
  13.  *
  14.  * Version: WORK
  15.  * Date: -
  16.  */
  17.  
  18.  
  19.  
  20. // --- Include Libraries ---
  21. #include <ModbusMaster.h>
  22. #include <SPI.h> // Needed for Ethernet.h
  23. #include <Ethernet.h>
  24. // --- ---
  25.  
  26.  
  27.  
  28. // --- Parameter and function declaration ---
  29. // Pins for the state LEDs
  30. uint8_t errorLED = 9; // Error-LED
  31. uint8_t okLED = 8; // OK-LED
  32. uint8_t processLED = 10; // Process-LED
  33.  
  34. // RS232/TTL-converter
  35. uint8_t ser1Pow = 6; // voltage source for the converter with the DSUB jack
  36.  
  37. byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address
  38. char serverAddress[] = "REPLACED"; // Receiver address
  39. char serverPath[] = "REPLACED"; // Path to the script that processes the request
  40.  
  41. void errorMessage(uint8_t rep, uint8_t clk); // Send an optical error message
  42. String getParameters(); // Get the electrical parameters from the power analyser
  43. // --- ---
  44.  
  45.  
  46.  
  47. // --- Instantiate objects ---
  48. ModbusMaster powerAnalyser; // Modbus
  49. EthernetClient receiveServer; // Ethernet
  50. // --- ---
  51.  
  52.  
  53.  
  54. // --- Initialization ---
  55. void setup() {
  56. // Pin initialization
  57. pinMode(errorLED,OUTPUT);
  58. pinMode(okLED,OUTPUT);
  59. pinMode(processLED,OUTPUT);
  60. pinMode(ser1Pow,OUTPUT);
  61.  
  62. // Turn LEDs on to show the initialization process
  63. digitalWrite(errorLED,HIGH);
  64. digitalWrite(okLED,HIGH);
  65. digitalWrite(processLED,HIGH);
  66.  
  67. // Modbus RTU
  68. // WARNING: The baud rate and the device address have to pass with the setting of the power analyser
  69. Serial1.begin(9600, SERIAL_8N2); // Start serial port for the Modbus (baudrate: 9600, data bits: 8, parity: none, stopp bits: 2) -- Don't change the databits or parity
  70. powerAnalyser.begin(1, Serial1); // Start Modbus over serial port 1 -- Address of the power analyser: 1
  71.  
  72. // Ethernet
  73. if(!Ethernet.begin(mac)) {
  74. if(Ethernet.hardwareStatus() == EthernetNoHardware) while(1) errorMessage(1,2); // Can't find Etherned-Board
  75. while(1) errorMessage(1,3); // Other fault
  76. }
  77. delay(2000); // Initialization time
  78.  
  79. digitalWrite(errorLED,LOW);
  80. digitalWrite(processLED,LOW);
  81. } // setup()
  82.  
  83.  
  84. // --- Main function ---
  85. void loop() {
  86. digitalWrite(okLED,HIGH); // Turn on OK-LED in case of a previous error
  87.  
  88. // Connect with the server
  89. if(receiveServer.connect(serverAddress, 80)) { // If successful send POST-request
  90. digitalWrite(processLED,HIGH);
  91. String parameters = getParameters();
  92.  
  93. receiveServer.print("POST ");
  94. receiveServer.print(serverPath);
  95. receiveServer.println(" HTTP/1.1");
  96. receiveServer.print("Host: ");
  97. receiveServer.println(serverAddress);
  98. receiveServer.println("Authorization: Basic REPLACED");
  99. receiveServer.println("Content-type: application/x-www-form-urlencoded");
  100. receiveServer.print("Content-length: ");
  101. receiveServer.println(parameters.length());
  102. receiveServer.println("Connection: close");
  103. receiveServer.println();
  104. receiveServer.println(parameters);
  105. digitalWrite(processLED,LOW);
  106. }
  107. else { // If fail
  108. errorMessage(1,4);
  109. }
  110.  
  111. //Serial.println(getParameters());
  112. delay(10000); // Do this ervery 10 seconds
  113. } // loop()
  114.  
  115.  
  116.  
  117. // Send an optical error message
  118. void errorMessage(uint8_t rep, uint8_t clk) {
  119. digitalWrite(okLED,LOW);
  120. digitalWrite(processLED,LOW);
  121. for(uint8_t i = 0; i < rep; i++) {
  122. for(uint8_t j = 0; j < clk; j++) {
  123. digitalWrite(errorLED,HIGH);
  124. delay(200);
  125. digitalWrite(errorLED,LOW);
  126. delay(200);
  127. }
  128. delay(500);
  129. }
  130. } // errorMessage()
  131.  
  132.  
  133.  
  134. // Get the electrical parameters from the power analyser
  135. String getParameters() {
  136. digitalWrite(ser1Pow,HIGH);
  137. digitalWrite(processLED,HIGH);
  138. String data = "values="; //"values=230;231;232;400;401;402;300;301;302;400;401;402;500;501;502;20;21;22;30;31;32;2;3;4;5;6;7;50;40;1;200;600;700;800;";
  139.  
  140. // Get first data group
  141. if(powerAnalyser.readHoldingRegisters(0xC8,21) == powerAnalyser.ku8MBSuccess) {
  142. for(uint8_t i = 0; i < 21; i++) {
  143. data = data + powerAnalyser.getResponseBuffer(i);
  144. data = data + ";";
  145. }
  146. } else { // Can't get parameters
  147. errorMessage(1,5);
  148. }
  149.  
  150. // Get second data group
  151. if(powerAnalyser.readHoldingRegisters(0x10D,13) == powerAnalyser.ku8MBSuccess) {
  152. for(uint8_t i = 0; i < 13; i++) {
  153. data = data + powerAnalyser.getResponseBuffer(i);
  154. data = data + ";";
  155. }
  156. } else { // Can't get parameters
  157. errorMessage(1,6);
  158. }
  159.  
  160. digitalWrite(processLED,LOW);
  161. digitalWrite(ser1Pow,LOW);
  162. return data;
  163. } // getParameters()