19.12.2012, 18:18 | #51 |
Junior Member
Регистрация: 19.12.2012
Адрес: Марбелья
Сообщений: 18
Вес репутации: 0 |
Сегодня, успешно завершил тест работы libmodbus
В качестве сервера работал роутер TP-Link TL-MR3220 v1, на котором установлен OpenWrt Attitude Adjustment 12.09-rc1.
libmodbus для роутера можно установить стандартными средствами (opkg install libmodbus) Тестовая программа (unit-test-client) собиралась стандартными средствами OpenWrt на Ubuntu. В качестве клиента работал LaunchPad MSP430 ( IDE energia-0101E0009 ), здесь работал немного модифицированный скетч из четвёрторо поста. Дело в том, что у LaunchPad есть два встроенных светодиода и датчик температуры. Вот их-то и задейсвовал. Slave ID = 1 Декларировано 10 регистров. Первый (0) и второй (1) регистр управляет включением-выключением светодиодов. Последний регистр (9) читает температуру процессора с встроенного термодатчика. В остальные регисры пишутся случайные числа. Исходник программы на C - Код:
#include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <modbus.h> #include "unit-test.h" #define SL_ID 1 int main(int argc, char *argv[]) { uint16_t tab_reg[64]; modbus_t *ctx; int i, n , rc; ctx = modbus_new_rtu("/dev/ttyACM0", 9600, 'N', 8, 1); if (ctx == NULL) { fprintf(stderr, "Unable to allocate libmodbus context\n"); return -1; } modbus_set_debug(ctx, TRUE); modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL); modbus_set_slave(ctx, SL_ID); if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } printf("** UNIT TESTING **\n"); printf("\nTEST WRITE/READ:\n"); tab_reg[0] = 0; tab_reg[1] = 1; for ( n=0 ; n<100 ; n++ ) { rc = modbus_read_registers(ctx, 0, 10, tab_reg); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return -1; } for (i=0; i < rc; i++) { printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); } if (tab_reg[0] == 1) tab_reg[0]=0; else tab_reg[0]=1; if (tab_reg[1] == 1) tab_reg[1]=0; else tab_reg[1]=1; tab_reg[2] = rand(); tab_reg[3] = rand(); tab_reg[4] = rand(); tab_reg[5] = rand(); tab_reg[6] = rand(); tab_reg[7] = rand(); tab_reg[8] = rand(); rc = modbus_write_registers(ctx, 0, 10, tab_reg); if (rc == -1) { fprintf(stderr, "%s\n", modbus_strerror(errno)); return -1; } for (i=0; i < rc; i++) { printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); } sleep(1); } /* Close the connection */ modbus_close(ctx); modbus_free(ctx); return 0; } Код:
#include <Modbusino.h> const int ledPin_g = GREEN_LED; const int ledPin_r = RED_LED; const int RL0 = GREEN_LED; const int RL1 = RED_LED; const int RL2 = 12; const int RL3 = 13; const int rl_arr[] = { RL0,RL1,RL2,RL3 }; const int regs = 10; // количество регистров const int ID_slave = 1; uint16_t tab_reg[regs]; //задаем массив регистров // Инициализация SLAVE, идентификатор (адрес) в сети ID = 1 ModbusinoSlave modbusino_slave(ID_slave); // на цифр. выходы сразу записываем значение регистров // любое значение > 0 это HIGH, 0 - LOW void SetRelay() { int i; for (i = 0; i < 4; i++) { digitalWrite(rl_arr[i], tab_reg[i]); } } void setup() { modbusino_slave.setup(9600); // установка цифровых вх/вых в режим выхода pinMode(RL0, OUTPUT); pinMode(RL1, OUTPUT); pinMode(RL2, OUTPUT); pinMode(RL3, OUTPUT); } void loop() { modbusino_slave.loop(tab_reg, regs); SetRelay(); tab_reg[9] = analogRead(TEMPSENSOR); //запись аналогового значения в 9-ый регистр } Код:
root@zuriuslev:~# /home/ServoManager/ACM0/unit-test-client Opening /dev/ttyACM0 at 9600 bauds (N, 8, 1) ** UNIT TESTING ** TEST WRITE/READ: [01][03][00][00][00][0A][C5][CD] Waiting for a confirmation... <01><03><14><00><00><00><01><99><38><E8><E0><CA><79><5C><4D><EA><3D><1A><34><5D><BC><01><3E><40><7D> reg[0]=0 (0x0) reg[1]=1 (0x1) reg[2]=39224 (0x9938) reg[3]=59616 (0xE8E0) reg[4]=51833 (0xCA79) reg[5]=23629 (0x5C4D) reg[6]=59965 (0xEA3D) reg[7]=6708 (0x1A34) reg[8]=23996 (0x5DBC) reg[9]=318 (0x13E) [01][10][00][00][00][0A][14][00][01][00][00][45][67][23][C6][98][69][48][73][DC][51][5C][FF][94][4A][01][3E][6A][82] Waiting for a confirmation... <01><10><00><00><00><0A><40><0E> reg[0]=1 (0x1) reg[1]=0 (0x0) reg[2]=17767 (0x4567) reg[3]=9158 (0x23C6) reg[4]=39017 (0x9869) reg[5]=18547 (0x4873) reg[6]=56401 (0xDC51) reg[7]=23807 (0x5CFF) reg[8]=37962 (0x944A) reg[9]=318 (0x13E) [01][03][00][00][00][0A][C5][CD] Метод отлично работает ! LaunchPad MSP430 весело моргает светодиодами и показывает изменения температуры Програмка для роутера в аттачменте |
19.12.2012, 18:43 | #52 |
Administrator
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,618
Вес репутации: 9823 |
Программу для роутера не совсем понял как запускать?
|
19.12.2012, 22:02 | #53 |
Junior Member
Регистрация: 19.12.2012
Адрес: Марбелья
Сообщений: 18
Вес репутации: 0 |
Продолжил разборки с modbus.
Хочу управлять шиной при помощи PHP.
НО ! для PHP, нашел вразумительные классы только для ModBus TCP, для ModBus RTU, ничего нет. Начал рыться и наткнулся на замечательную программу - Free MODBUS/TCP to MODBUS/RTU gateway Действительно ! скомпилировал, запустил на роутере (mbusd -d -v9 -L- -p/dev/ttyACM0 -s9600 -P502) и подключился уже с виндозы, через ModbusPoll. Всё работает ! Даже собрал .ipk для OpenWrt. Завтра продолжу уже из PHP. |
19.12.2012, 22:05 | #54 |
Junior Member
Регистрация: 19.12.2012
Адрес: Марбелья
Сообщений: 18
Вес репутации: 0 |
Скопировать на роутер. (Например в /usr/bin)
Сделать "chmod 755 /usr/bin/unit-test-client" и запустить unit-test-client Немножко доработал прогу, новое название mbtest Usage: mbtest [-p name] [-s value] [-e value] -p<name> set serial port device name (default /dev/ttyACM0) -s<value> set serial port speed (default 9600) -e<value> set slave id (default 1) Т.Е можно изменять порт, скорость и номер слейв устройства, запуск без параметров эквивалентен комманде - mbtest -p ttyACM0 -s 9600 -e 1 список параметров - mbtest -h комплект прилагается. Последний раз редактировалось zuriuslev; 20.12.2012 в 02:15. |
20.12.2012, 04:53 | #55 |
Senior Member
Регистрация: 16.09.2012
Адрес: Irkutsk
Сообщений: 555
Вес репутации: 1605 |
Отлично наш человек!
PHP хорошо работает через сокеты. Вот пример клиента: PHP код:
PHP код:
Код:
Arduino (slave) <---> Modbus RTU (Master) - Sokcet TCP(Server) <---> PHP Socket TCP (Client) -- Web страница Хотя если использовать библиотеки от нашей версии то... Последний раз редактировалось andr128; 20.12.2012 в 15:08. |
20.12.2012, 14:44 | #56 |
Senior Member
Регистрация: 16.09.2012
Адрес: Irkutsk
Сообщений: 555
Вес репутации: 1605 |
Для тех кто хочет поуправлять ардуиной с Web сервера (без модбас) можно использовать шлюз server serial-tcp: ser2net (есть в репозитории) или suart.
Стучаться к нему соответственно через сокет (пример на PHP выше) указав порт TCP. Пример html страницы. (Используется JQuery, JSON, AJAX - фоновое обновление параметров): Код HTML:
<html> <head> <meta http-equiv="Content-Type" content="text/html; Charset=UTF-8"> <script type="text/javascript" src="jquery.js"></script> </head> <body> <div id="info">Загрузка...</div> <script> function json_example() { $.getJSON('client_socket.php', function(data) { s = ""; $.each(data, function(key, val) { s= s + key+' = ' + val + '<br/>' }); $("#out").html(s) }); } setInterval(json_example, 1000); //вызывать скрипт через 1 с // json_example(); //вызвать 1 раз </script> <div id="out"></div> </body> </html> Пример вывода отдельных элементов массива текстовой структуры JSON Код HTML:
<html> <head> <meta http-equiv="Content-Type" content="text/html; Charset=UTF-8"> <script type="text/javascript" src="jquery.js"></script> </head> <body> <div id="info"> Данные с сервера php </div> <script> function json_example() { $.getJSON('client_socket.php', function(data) { $("#out").html(" ID : " +data.id+"<br>"+ " Server : " +data.server+"<br>"+ " Time : " +data.time); } ); } setInterval(json_example, 1000); //вызывать скрипт через 1000 мс </script> <div id="out"></div> <!-- сюда будет выводится страница --> </body> </html> Последний раз редактировалось andr128; 26.01.2013 в 08:21. |
20.12.2012, 15:03 | #57 |
Senior Member
Регистрация: 16.09.2012
Адрес: Irkutsk
Сообщений: 555
Вес репутации: 1605 |
тестовый код управление ардуиной по Modbus RTU
PHP код:
|
20.12.2012, 15:46 | #58 |
Member
|
ANDR128 Пример сервера для работы с сокетами:
Скрипт написан на PHP--??? |
20.12.2012, 17:04 | #59 | |
Senior Member
Регистрация: 16.09.2012
Адрес: Irkutsk
Сообщений: 555
Вес репутации: 1605 |
Цитата:
Пример клиента написан на PHP. Для более полного понимания нарисовал картинку Последний раз редактировалось andr128; 20.12.2012 в 17:50. |
|
20.12.2012, 17:12 | #60 |
Junior Member
Регистрация: 19.12.2012
Адрес: Марбелья
Сообщений: 18
Вес репутации: 0 |
|
Здесь присутствуют: 6 (пользователей: 0 , гостей: 6) | |
|
|