directman

Екатеринбург, Россия

На форуме: directman66


 
<<< Back

чтение мгновенных данных U,P, I электросчетчика милур 104

Делюсь своим вариантом получения потребляемой мощности и напряжения.

Роутер c usb, в моем примере asus rt-n66u, установлен в непосредственной близости к счетчику. У счетчика Милур 104 [spoiler=][img]http://www.all-pribors.ru/pics/original/51369-12-0000.jpg[/img][/spoiler] есть порт rs485. В роутер вставлен китайский преобразователь rs485-usb [spoiler=][img]http://carduino.ru/images/product_images/popup_images/rs485.jpg[/img][/spoiler]
На роутере установлена прошивка asuswrt-merilin и пакет optware. Нам требуется доустановить coreutils, ser2net и настроить их.

Для того, чтобы железяка успешно стартовала и передавала параметры, необходимо было найти и прописать модуль устройства. Иначе преобразователь работал как модем и посылал какой-то шум.

Извиняюсь, что много ошибок в тексте. Времени уже много (

Скрипт автозапуска роутера:

    admin@RT-N66U-8A78:/tmp/home/root# cat /jffs/scripts/mydevice-start.sh
    #!/bin/sh
    DEVICE="/dev/ttyUSB0"
    SPEED=9600
    PRODUCT="1a86:7523"  # u-blox GPS receiver

    # wait for device to become ready
    modprobe cdc-acm
    insmod /jffs/scripts/ch341.ko
    ser2net -C "3000:raw:60:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS"
    ser2net -C "3001:raw:60:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS"
    ser2net -C "3002:raw:60:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS"
    ser2net -C "3003:raw:60:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS"
    ser2net -C "3004:raw:60:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS"
    ser2net -C "3005:raw:60:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS"
    ser2net -C "3006:raw:60:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS"
    ser2net -C "3007:raw:60:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS"

    while : ; do
    lsusb | grep -qi "$PRODUCT"
    if [ $? -eq 0 ]; then
    break
      else
        sleep 5
      fi
    done

    stty -F $DEVICE $SPEED raw -clocal -echo icrnl

Ссылки на модуль внизу 1 сообщения.

Скрипт обработки запроса МД к роутеру

    function strToHex($string){
    $hex='';
        for ($i=0; $i < strlen($string); $i++){
            $hex .= dechex(ord($string[$i]));
        }
        return $hex;
    }

    function hexToStr($hex){
        $string='';
        for ($i=0; $i < strlen($hex)-1; $i+=2){
            $string .= chr(hexdec($hex[$i].$hex[$i+1]));
        }
        return $string;
    }

    function hex2str($hex) {
        $str = '';
        for($i=0;$i<strlen($hex);$i+=2) $str .= chr(hexdec(substr($hex,$i,2)));
        return $str;
    }
    $host="192.168.1.1";
    $port=3000;
       $socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname("tcp"));  // Create Socket
            if (socket_connect($socket, $host, $port)) {  //Connect
    //circle 1
            $sendStr = 'ff 08 00 ff ff ff ff ff ff 4f 2d';  // 16 hexadecimal data
            $sendStrArray = str_split(str_replace(' ', '', $sendStr), 2);  // The 16 binary data into a set of two arrays
         
                          for ($j = 0; $j <count ($sendStrArray); $j++) {
                                  socket_write ($socket, Chr (hexdec ($sendStrArray[$j])));   // by group data transmission
                    }
                    $receiveStr = "";
                    $receiveStr = socket_read($socket, 1024, PHP_BINARY_READ);  // The 2 band data received 
                              $receiveStrHex = bin2hex ($receiveStr);   // the 2 hexadecimal data convert 16 hex
                 echo  "send:".$sendStr ; 
                 echo " answer:" . $receiveStr;   
                 echo " answerSTR:" .hex2str($receiveStrHex);
                 echo " answerHEX:" . $receiveStrHex.'<br>';
                     //цикл 2
                $sendStr = 'ff 01 20 41 b8';  // модель
                $sendStrArray = str_split(str_replace(' ', '', $sendStr), 2);  // The 16 binary data into a set of two arrays
                              for ($j = 0; $j <count ($sendStrArray); $j++) {
                                      socket_write ($socket, Chr (hexdec ($sendStrArray[$j])));   // by group data transmission
                    }
                $receiveStr = "";
                $receiveStr = socket_read($socket, 1024, PHP_BINARY_READ);  // The 2 band data received 
                          $receiveStrHex = bin2hex ($receiveStr);   // the 2 hexadecimal data convert 16 hex
             echo  "send:".$sendStr ; 
             echo " answer:" . $receiveStr;   
             echo " answerSTR:" .hex2str($receiveStrHex);
             echo " answerHEX:" . $receiveStrHex.'<br>';
             //цикл 3
            $sendStr = 'ff 01 03 00 61';  // P
            $sendStrArray = str_split(str_replace(' ', '', $sendStr), 2);  // The 16 binary data into a set of two arrays
                                      for ($j = 0; $j <count ($sendStrArray); $j++) {
                                           socket_write ($socket, Chr (hexdec ($sendStrArray[$j])));   // by group data transmission
                        }
                        $receiveStr = "";
                        $receiveStr = socket_read($socket, 1024, PHP_BINARY_READ);  // The 2 band data received 
                                  $receiveStrHex = bin2hex ($receiveStr);   // the 2 hexadecimal data convert 16 hex
                $phex=substr($receiveStrHex,12,2).substr($receiveStrHex,10,2).substr($receiveStrHex,8,2);
                $p=hexdec($phex)/1000;          
                     echo  "P:".$sendStr ; 
                     echo " answer:" . $receiveStr;   
                     echo " answerSTR:" .hex2str($receiveStrHex);
                     echo " answerHEX:" . $receiveStrHex;
                      echo " answerPHEX:" . $phex;   
                      echo " answerP:" . $p.'<br>';
                            sg("current.P",$p);  
                    //цикл 4
                    $sendStr = 'ff 01 01 81 a0 ';  // U
                    $sendStrArray = str_split(str_replace(' ', '', $sendStr), 2);  // The 16 binary data into a set of two arrays
                                  for ($j = 0; $j <count ($sendStrArray); $j++) {
                                          socket_write ($socket, Chr (hexdec ($sendStrArray[$j])));   // by group data transmission
                    }
                $receiveStr = "";
                $receiveStr = socket_read($socket, 1024, PHP_BINARY_READ);  // The 2 band data received 
                          $receiveStrHex = bin2hex ($receiveStr);   // the 2 hexadecimal data convert 16 hex
       
        $uhex=substr($receiveStrHex,12,2).substr($receiveStrHex,10,2).substr($receiveStrHex,8,2);
        $u=hexdec($uhex)/1000;       
         echo  "U:".$sendStr ; 
             echo " answer:" . $receiveStr;   
             echo " answerSTR:" .hex2str($receiveStrHex);
             echo " answerHEX:" . $receiveStrHex;    
              echo " answerUHEX:" . $uhex;   
              echo " answerU:" . $u.'<br>'; 
                 sg("current.U",$u);
            }
            socket_close($socket);  // Close Socket

Декодировка протокола обмена проводилась по примеру протокола меркуриев. Родной протокол взаимодействия найти не удалось.

В планах научиться получать значения счетчиков раз в месяц.

Ссылка на архив драйвера https://yadi.sk/d/wwdJCkmA3PbRsc
Ссылка на модуль в отдельности https://yadi.sk/d/Hv4FDzD33PbRxu
Ссылка на протокол меркурий (очень похож) https://yadi.sk/i/9LlIbMyM3PbpyG
Руководство на счетчик https://yadi.sk/i/y4ZmytsD3Pc4Pu

upd: разработчик прислал описание протокола милур! https://yadi.sk/i/sVrkf7Wk3PdvDA

Discuss (0) (0)