|
<?php |
|
function set_win_port_attr ($port_name = 'com1:', $port_attr = ['baud' => 9600, 'data' => 8, 'stop' => 1, 'parity' => 'n']) { |
|
$mode = 'mode ' . $port_name; |
|
foreach ($port_attr as $attr => $value) { |
|
$mode .= ' ' . $attr . '=' . $value; |
|
} |
|
|
|
exec($mode, $output, $return); |
|
|
|
return $return; |
|
} |
|
|
|
function crc16 ($data) { |
|
$crc = 0xFFFF; |
|
foreach (unpack('C*', $data) as $byte) { |
|
$crc ^= $byte; |
|
for ($j = 8; $j; $j--) { |
|
$crc = ($crc >> 1) ^ (($crc & 0x0001) * 0xA001); |
|
} |
|
} |
|
|
|
return pack('v1', $crc); |
|
} |
|
|
|
$modbus_message_format = [ |
|
'address' => 'C1', |
|
'function' => 'C1', |
|
'start' => 'n1', |
|
'quantity' => 'n1', |
|
//'crc' => 'n1', |
|
]; |
|
|
|
$modbus_message_pack = implode($modbus_message_format); |
|
$modbus_message_unpack = null; |
|
foreach ($modbus_message_format as $name => $format) { |
|
$modbus_message_unpack .= $format . $name . '/'; |
|
} |
|
|
|
$modbus_response_format = [ |
|
'address' => 'C1', |
|
'function' => 'C1', |
|
'count' => 'C1', |
|
'total_energy' => 'N1', |
|
'reserved' => 'N3', |
|
'export_energy' => 'N1', |
|
'import_energy' => 'N1', |
|
'voltage' => 'n1', |
|
'current' => 'n1', |
|
'active_power' => 'n1', |
|
'reactive_power' => 'n1', |
|
'power_factor' => 'n1', |
|
'frecuency' => 'n1', |
|
//'year' => 'C1', |
|
//'month' => 'C1', |
|
//'day' => 'C1', |
|
//'hour' => 'C1', |
|
//'minute' => 'C1', |
|
//'second' => 'C1', |
|
//'comm_addr' => 'C1', |
|
//'comm_baud' => 'C1', |
|
//'trip_energy' => 'N1', |
|
//'trip_time' => 'N1', |
|
//'unknow' => 'n5', |
|
//'month2' => 'C1', |
|
//'day2' => 'C1', |
|
'crc' => 'n1', |
|
]; |
|
|
|
$modbus_response_pack = implode($modbus_response_format); |
|
$modbus_response_unpack = null; |
|
foreach ($modbus_response_format as $name => $format) { |
|
$modbus_response_unpack .= $format . $name . '/'; |
|
} |
|
|
|
$port_name = 'COM3:'; |
|
$port_attr = ['baud' => 9600, 'data' => 8, 'stop' => 1, 'parity' => 'n', 'xon' => 'off']; |
|
set_win_port_attr($port_name, $port_attr); |
|
|
|
$modbus = fopen($port_name, 'rb+'); |
|
|
|
$message = [0x01, 0x03, 0, 18]; |
|
$message = pack($modbus_message_pack, ...$message); |
|
$message .= crc16($message); |
|
|
|
fwrite($modbus, $message); |
|
|
|
$buffer = null; |
|
do { |
|
usleep($buffer ? 5000 : 100000); |
|
$buffer .= fread($modbus, 1); |
|
} while (!feof($modbus)); |
|
|
|
if (crc16(substr($buffer, 0, -2)) != substr($buffer, -2)) { |
|
echo __LINE__, PHP_EOL; |
|
echo bin2hex($buffer), PHP_EOL; |
|
echo bin2hex(substr($buffer, 0, -2)), PHP_EOL; |
|
echo bin2hex(substr($buffer, -2)), PHP_EOL; |
|
die(); |
|
} |
|
|
|
$response = unpack($modbus_response_unpack, $buffer); |
|
|
|
//print_r($response); |
|
|
|
$data_scale = [ |
|
'total_energy' => 1/100, // daWh / 100 => kWh |
|
'export_energy' => 1/100, // daWh / 100 => kWh |
|
'import_energy' => 1/100, // daWh / 100 => kWh |
|
'voltage' => 1/10, // dV / 10 => V |
|
'current' => 1/100, // cA / 100 => A |
|
'active_power' => 1, // W |
|
'reactive_power' => 1, // VA |
|
'power_factor' => 1/1000, |
|
'frecuency' => 1/100, // cHz / 100 => Hz |
|
//'comm_addr' => 1, |
|
//'comm_baud' => 1, // [1 => 9600, 2 => 4800, 3 => 2400, 4 => 1200] |
|
//'trip_energy' => 1/100, // daWh / 100 => kWh |
|
]; |
|
|
|
$data = []; |
|
foreach ($data_scale as $key => $scale) { |
|
$data[$key] = isset($response[$key]) ? $response[$key] * $scale : null; |
|
} |
|
|
|
print_r($data); |
|
|
|
echo "\nok"; |
|
fclose($modbus); |
Hola,
Estoy buscando un programa para ejecutarlo en Arduino mega.
Dispongo de un módulo max485.
Mis conocimientos son bastante limitados.
Si me podéis hechar una mano os lo agradecería.
He probado algunos ejemplos sin éxito.