Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> драйвер для лазерного сканера на boost::asio, помощь в написании драйвера. open source 
:(
    Опции темы
avmartugin
Дата 17.6.2012, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.6.2012

Репутация: нет
Всего: нет



В исходном состоянии лазерный сканер настроен для работы в сети с DHCP-
сервером. Данную настройку можно отключить и настроить параметры сканера (описание
параметров см. ниже) для работы с определённым IP-адресом, маской сети. Предполага-
ется функционирование сканера с двумя типами протоколов, а именно, UDP и TCP/IP. 
UDP протокол. 
UDP протокол используется для: 
1) обнаружения сканера в сети. 
При подключении к сети и включении питания сканер с периодичностью раз в 2  се-
кунды рассылает широковещательный информационный пакет с порта 6000 на порт 6001. 
Поиск устройства осуществляется посредством библиотечной функции RF_Search  (см. 
ниже). 
2) передачи измеренных значений  
При передаче измеренных значений UDP пакет, состоящий из 4098 байт, передается с
порта 6002 на заданный порт хоста и IP адрес хоста. 
TCP/IP протокол
Данный протокол используется для конфигурирования и проверки основных функ-
ций сканера. При активном TCP/IP соединении UDP пакеты не передаются.

Добавлено @ 14:16
Код

#include <ctime>
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>

#include <boost/date_time/posix_time/posix_time.hpp>

#include "udpserver.h"
#include "sensormanager.h"

using boost::asio::ip::udp;

void service_stop(const boost::system::error_code& /*error*/,
        const boost::asio::io_service* io) {
    io->stop();
}

void handle_receive(const boost::system::error_code& error,
        std::size_t /*bytes_transferred*/,
        const boost::array<char, 10>& buffer) {
    std::cout << buffer.data() << std::endl;
}

int main() {
    boost::array<char, 10> buffer;

    boost::asio::io_service io;
    udp::socket socket(io, udp::endpoint(udp::v4(), 6001));
    udp::endpoint remote_endpoint;
    boost::system::error_code error;

    if (error && error != boost::asio::error::message_size)
        throw boost::system::system_error(error);

    boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
    t.async_wait(
            boost::bind(service_stop, boost::asio::placeholders::error, &io));

    socket.async_receive_from(boost::asio::buffer(buffer), remote_endpoint,
            boost::bind(&handle_receive, boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred, buffer));

    io.run();

    return 0;
}


не получается реализовать функцию поиска датчика, которая состоит в том чтобы отлавливать пакеты пришедшие на порт 6001 со всех датчиков в течении короткого промежутка времени и записать все адреса датчиков в сети в массив. далее их использовать.
пробую передать на порт 6001 пакеты и ничего не происходит (на стандартном выводе нет массива символов которые я передаю)

информация на сайте производителя по сканеру
http://www.riftek.com/pages/2d.htm

Это сообщение отредактировал(а) avmartugin - 17.6.2012, 14:28
PM MAIL   Вверх
boostcoder
Дата 17.6.2012, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



попробуй так:
Код

#include <ctime>
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

using boost::asio::ip::udp;

void handle_receive(const boost::system::error_code& error,
        std::size_t /*bytes_transferred*/,
        const boost::array<char, 10>& buffer) {
    std::cout << "error: " << error << std::endl;
    std::cout << buffer.data() << std::endl;
}

int main() {
    boost::array<char, 10> buffer;
    boost::asio::io_service io;

    udp::socket socket(io, udp::endpoint(udp::v4(), 6001));

    udp::endpoint remote_endpoint;
    boost::system::error_code error;

    if (error && error != boost::asio::error::message_size)
        throw boost::system::system_error(error);

    socket.async_receive_from(boost::asio::buffer(buffer), remote_endpoint,
        boost::bind(
            &handle_receive
            ,boost::asio::placeholders::error
            ,boost::asio::placeholders::bytes_transferred
            ,boost::cref(buffer)
        )
    );
    
    io.run();
    
    return 0;
}


и покажи вывод.

PM WWW   Вверх
avmartugin
Дата 17.6.2012, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.6.2012

Репутация: нет
Всего: нет



Цитата(boostcoder @ 17.6.2012,  14:54)
попробуй так:
Код

#include <ctime>
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

using boost::asio::ip::udp;

void handle_receive(const boost::system::error_code& error,
        std::size_t /*bytes_transferred*/,
        const boost::array<char, 10>& buffer) {
    std::cout << "error: " << error << std::endl;
    std::cout << buffer.data() << std::endl;
}

int main() {
    boost::array<char, 10> buffer;
    boost::asio::io_service io;

    udp::socket socket(io, udp::endpoint(udp::v4(), 6001));

    udp::endpoint remote_endpoint;
    boost::system::error_code error;

    if (error && error != boost::asio::error::message_size)
        throw boost::system::system_error(error);

    socket.async_receive_from(boost::asio::buffer(buffer), remote_endpoint,
        boost::bind(
            &handle_receive
            ,boost::asio::placeholders::error
            ,boost::asio::placeholders::bytes_transferred
            ,boost::cref(buffer)
        )
    );
    
    io.run();
    
    return 0;
}


и покажи вывод.

error: system:234
1111111111

нашел: написано что еще есть данные, исправил отправляемое мной сообщение и ошибка исчезла! но программа сразу после получения 1 сообщения закрывается. буду копать дальше

Это сообщение отредактировал(а) avmartugin - 17.6.2012, 15:36
PM MAIL   Вверх
boostcoder
Дата 17.6.2012, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(avmartugin @  17.6.2012,  15:00 Найти цитируемый пост)
программа сразу после получения 1 сообщения закрывается

согласно приведенному коду - так и должно быть ;)

Добавлено через 1 минуту и 46 секунд
Цитата(avmartugin @  17.6.2012,  15:00 Найти цитируемый пост)
error: system:234

на какой ОСи проверяешь?

PM WWW   Вверх
avmartugin
Дата 17.6.2012, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.6.2012

Репутация: нет
Всего: нет



Цитата(boostcoder @ 17.6.2012,  16:02)
Цитата(avmartugin @  17.6.2012,  15:00 Найти цитируемый пост)
программа сразу после получения 1 сообщения закрывается

согласно приведенному коду - так и должно быть ;)

Добавлено @ 16:03
Цитата(avmartugin @  17.6.2012,  15:00 Найти цитируемый пост)
error: system:234

на какой ОСи проверяешь?


на винде. boost выбрал чтобы драйвер мог работать в любой ОС (использование драйвера в будущем планируется на linux RT, будет ведь работать?)

я в курсе, сейчас работаю над тем чтобы он прослушивал сообщения в течении 5 сек и потом закрывал сокет
кстати, есть ли возможность передать в качестве буфера свою собственную структуру с определенными полями


Код

struct my_struct {
std::bitset<3> sync_option;
boost::array<char, 3> some_option;

...etc.
}


Это сообщение отредактировал(а) avmartugin - 17.6.2012, 16:11
PM MAIL   Вверх
boostcoder
Дата 17.6.2012, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(avmartugin @  17.6.2012,  16:09 Найти цитируемый пост)
в будущем планируется на linux RT, будет ведь работать?

тут смотри. на linux RT я asio не юзал.

Цитата(avmartugin @  17.6.2012,  16:09 Найти цитируемый пост)
есть ли возможность передать в качестве буфера свою собственную структуру с определенными полями

на-прямую - нет.
напиши свою перегрузку для async_receive_from() принимающую твою структуру.

PM WWW   Вверх
avmartugin
Дата 17.6.2012, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.6.2012

Репутация: нет
Всего: нет



Код

#include <ctime>
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
using boost::asio::ip::udp;

void service_stop(const boost::system::error_code& error,
        const udp::socket& socket,
        const boost::asio::io_service::work& work) {
    socket.shutdown(boost::asio::ip::udp::socket::shutdown_both);
    socket.close();
    (work.get_io_service()).stop();
}

void handle_receive(const boost::system::error_code& error,
        std::size_t /*bytes_transferred*/,
        const boost::array<char, 10>& buffer) {
    /*std::cout << "error: " << error.message() << std::endl;*/
    std::cout << buffer.data() << std::endl;
}
int main() {
    boost::array<char, 10> buffer;
    boost::asio::io_service io;
    boost::asio::io_service::work work(io);
    udp::socket socket(io, udp::endpoint(udp::v4(), 6001));
    udp::endpoint remote_endpoint;
    boost::system::error_code error;

    boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
    t.async_wait(
         boost::bind(&service_stop,
                 boost::asio::placeholders::error,
                 boost::cref(socket),
                 boost::cref(work))
    );

    if (error && error != boost::asio::error::message_size)
        throw boost::system::system_error(error);

    socket.async_receive_from(boost::asio::buffer(buffer), remote_endpoint,
        boost::bind(
            &handle_receive,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred,
            boost::cref(buffer)
        )
    );

    io.run();

    return 0;
}


это работает 5 сек и вырубается. но принимает только 1 сообщение (при приеме не вырубается). где ошибка я чет не пойму

Это сообщение отредактировал(а) avmartugin - 17.6.2012, 16:44
PM MAIL   Вверх
boostcoder
Дата 17.6.2012, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



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

PM WWW   Вверх
avmartugin
Дата 17.6.2012, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.6.2012

Репутация: нет
Всего: нет



Цитата(boostcoder @ 17.6.2012,  16:51)
в двух словах объясни задачу, я что-то запутался...
в топике написано одно, а в коде ты делаешь другое...

хочу на время (допустим 5 сек) открыть udp сокет на хосте порт 6001. принять все пакеты с различных адресов (этих датчиков будет 8 штук, они в локалке с компом организующим их работу), затем составить список этих адресов (реализую потом) и дальше с ними работать по инструкции.
вообще говоря io_service должен работать всегда я его выключаю чтобы программа завершилась просто чтобы отследить истечение 5 сек

мне сейчас хотелось бы увидеть что он принимает сколько угодно определенных структур (пока это char[10] для теста) и выводит все на экран чтобы быть уверенным что этот кусок кода адекватно работает. датчики и сам комп находятся в цеху, куда лишний идти нет совершенно никакого желания  smile 
PM MAIL   Вверх
boostcoder
Дата 17.6.2012, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(avmartugin @  17.6.2012,  17:02 Найти цитируемый пост)
хочу на время (допустим 5 сек) открыть udp сокет

зачем на время? почему не держать сокет открытым?

и как этот код узнает что получил пакеты от всех датчиков? разве один датчик не может дважды отправить сообщение, а твой код его дважды поймать?
задача не полностью сформулирована. (мне не интересно что будет происходит с полученными пакетами.)


Это сообщение отредактировал(а) boostcoder - 17.6.2012, 17:14
PM WWW   Вверх
avmartugin
Дата 17.6.2012, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.6.2012

Репутация: нет
Всего: нет



Цитата(boostcoder @ 17.6.2012,  17:08)
Цитата(avmartugin @  17.6.2012,  17:02 Найти цитируемый пост)
хочу на время (допустим 5 сек) открыть udp сокет

зачем на время? почему не держать сокет открытым?

и как этот код узнает что получил пакеты от всех датчиков? разве один датчик не может дважды отправить сообщение, а твой код его дважды поймать?
задача не полностью сформулирована. (мне не интересно что будет происходит в полученными пакетами.)

датчики посылают пакет раз в 2 сек (широковещательный как я понял), сокет открытым держать конечно можно, но это будет заставлять комп лишний раз обрабатывать ненужные пакеты (поиск датчиков осуществляется 1 лишь раз за все время работы программы). мой код должен поймать лишь уникальные адреса датчиков (это я надеюсь реализовать на основе std::set, который соберет только уникальные адреса датчиков)
PM MAIL   Вверх
boostcoder
Дата 17.6.2012, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



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

я все правильно понял?

PM WWW   Вверх
avmartugin
Дата 17.6.2012, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.6.2012

Репутация: нет
Всего: нет



Цитата(boostcoder @ 17.6.2012,  17:28)
из всего описанного, я задачу понял так: раз в пять секунд выполнять прием пакетов. прием пакетов продолжается до тех пор, пока не будут приняты пакеты от N устройств.

я все правильно понял?

будет большой проект где драйвер устройств будет лишь средством получения данных с датчиков

будет описан класс sensor_manager реализующий функцию sensors_search(...:ptime& expiered_time)

внутри sensor_manager будет std::set со всеми датчиками (количество датчиков заранее неизвестно!!! но все датчики неприменно будут идентифицированы т.к. каждый из них независимо от других посылает раз в 2 сек пакет с инфой о себе, главное чтобы expiered_time был больше 2 сек, для примера используется 5 сек).

мне сейчас на данном этапе нужно реализовать такой sensor_manager, которым бы можно было пользоваться в любом проекте и на любой платформе. он всего лишь должен управлять датчиками (запись/чтение параметров, получение карты с точками и т.д.)


sensor_manager должен через функцию sensors_search найти все датчики сколько бы их не было.

sensor_manager::sensors_search(...:ptime& expiered_time) будет вызван заранее неизвестное количество раз (зависит от пользователя системы, например рабочий может отключить от сети питания один/несколько датчиков и затем включить или не включать их, затем нажав кнопку "обновить поиск датчиков" найти все датчики которые доступны в данный момент)

так что алгоритм такой:

1. используя всегда работающий сервис io_service открыть сокет на порте 6001
2. принимать пакеты от датчиков
3. с приходом пакета добавлять к std::set<sensor> sensors вновь созданный объект класса sensor (содержит адрес и настройки датчика, настройки приходят в пакете который передает датчик в широковещательном пакете)
4. перейти к пункту (2)

цикл 2-4 должен повторяться пока не будет истечен таймер в указанное количество секунд

PM MAIL   Вверх
avmartugin
Дата 17.6.2012, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.6.2012

Репутация: нет
Всего: нет



ЕСТЬ ОТВЕТ!
код. 3 файла.


openRF620.cpp

Код

#include <boost/asio.hpp>

#include "sensormanager.h"

int main() {
    boost::asio::io_service io_service;
    boost::asio::io_service::work work(io_service);

    sensor_manager sensorManager(io_service);
    sensorManager.sensor_search(boost::posix_time::seconds(5));

    io_service.run();

    sensorManager.show_sensors();

    return 0;
}


sensormanager.h

Код

#ifndef SENSORMANAGER_H_
#define SENSORMANAGER_H_

#include <ctime>
#include <iostream>
#include <string>
#include <set>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/time_duration.hpp>

using boost::asio::ip::udp;

#include "common_defs.h"

class sensor_manager {
public:
    sensor_manager(boost::asio::io_service& io_service)
    :
        io_service_(io_service),
        sensor_info_socket_(io_service, udp::endpoint(udp::v4(), rf620_info_port)),
        timer_(io_service)
    {
    }
    void sensor_search(const boost::posix_time::time_duration& expiry_time);
    void show_sensors();
    //~sensor_manager();

private:
    boost::asio::io_service& io_service_;
    udp::socket sensor_info_socket_;
    boost::array<char, 10> buffer;
    udp::endpoint remote_endpoint;
    boost::asio::deadline_timer timer_;
    std::set<boost::asio::ip::address> sensor_address_list_;

    void service_stop(const boost::system::error_code& error);
    void rcv_handler();
};

#endif /* SENSORMANAGER_H_ */



sensormanager.cpp

Код

#include "sensormanager.h"

void sensor_manager::service_stop(const boost::system::error_code& error) {
    sensor_info_socket_.shutdown(boost::asio::ip::udp::socket::shutdown_both);
    sensor_info_socket_.close();
    io_service_.stop();
}

void sensor_manager::sensor_search(
        const boost::posix_time::time_duration& expiry_time) {

    sensor_info_socket_.async_receive_from(boost::asio::buffer(buffer),
            remote_endpoint,
            boost::bind(&rcv_handler, this));

    timer_.expires_from_now(expiry_time);
    timer_.async_wait(boost::bind(&service_stop, this, boost::asio::placeholders::error));

    //sensor_info_socket_.receive_from(block.buffer, remote_endpoint);
}

void myfunction(boost::asio::ip::address address) {
    std::cout << address.to_string() << std::endl;
}

void sensor_manager::rcv_handler(){
    std::cout << buffer.data() << std::endl;
    sensor_info_socket_.async_receive_from(boost::asio::buffer(buffer),
                remote_endpoint,
                boost::bind(&rcv_handler, this));
    sensor_address_list_.insert(remote_endpoint.address());
}

void sensor_manager::show_sensors() {
    std::for_each(sensor_address_list_.begin(), sensor_address_list_.end(),
            myfunction);

}


буст рулит  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0687 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.