Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Опросить слейвы по CAN.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Jenya7
Есть мастер и три слейва. У каждого слейва три параметра. Мне нужно за один опрос взять все три параметра с каждого слейва.
То есть для принятия решения мне нужно все 9 параметров. Потом я делаю свои дела и потом делаю новый опрос слейвов.
Вопрос как знать что все слейвы ответили именно на этот опрос? Есть какое то красивое решение или как всегда обычно?
adnega
Цитата(Jenya7 @ Feb 7 2018, 09:20) *
Вопрос как знать что все слейвы ответили именно на этот опрос?

Добавить в пакеты поле "идентификатор запроса".
mrKirill
Что изменится, если все условные Slave будут постоянно вещать в шину, а условный Master когда ему угодно будет принимать посылки? Точно нужна система запрос-ответ?

В одном из оборудований Bosch встречался вариант, когда в посылке из 8 байт последний отводился под номер посылки, от 0 до 255 и далее по кругу.
Jenya7
Допустим при посылке вместе с данными я буду посылать номер опроса.
А при приеме если пришел тот же номер опроса выставлять флаг на каждый параметер.
Код
uint32_t CAN_GetMessage(void)
{
    uint32_t mot_idx;
    uint32_t opcode;
    uint32_t message_num;
    
    uint8_t position;
  
    CAN_Receive(CAN1, can_params.fifo_num,  &RxMessage);
    
    mot_idx = (RxMessage.StdId >> 8);
    
    opcode = (RxMessage.StdId - (mot_idx * 0x100));
          
    switch (opcode)
    {      
        case CAN_COM_IGET:
            motor_data[mot_idx].current = (RxMessage.Data[3]<<24) | (RxMessage.Data[2]<<16) |
                                          (RxMessage.Data[1]<<8)  | RxMessage.Data[0];
            position = CAN_IGET_POS;
        break;
        
        case CAN_COM_PGET:
            motor_data[mot_idx].position = (int32_t)((RxMessage.Data[3]<<24) | (RxMessage.Data[2]<<16) |
                                           (RxMessage.Data[1]<<8)  | RxMessage.Data[0]);
            position = CAN_PGET_POS;
        break;
        
        case CAN_COM_SGET:
            motor_data[mot_idx].speed = (RxMessage.Data[3]<<24) | (RxMessage.Data[2]<<16) |
                                        (RxMessage.Data[1]<<8)  | RxMessage.Data[0];
            position = CAN_SGET_POS;
        break;
    }
    
    message_num = (RxMessage.Data[7]<<8) | RxMessage.Data[6];
    if (can_message_num == message_num)
    {
         motor_data[mot_idx].can_rx_flags |= (1<<position);
    }
  
     return CAN_OK;
}

и потом проверять
Код
uint32_t MOT_DataReady(void)
{
    int i;
    uint32_t resp = 0;
    
    //check if all motors replied
    for (i = 0; i < MAX_MOTORS; i++)
    {
        if (motor_data[i].ena)
        {
            if ((motor_data[i].can_rx_flags & 0x0F) == 0x0F)
                resp++;
        }      
    }
    
    //all motors responded with all data
    if (resp == g_motors_num)
    {
        //clear all flags - get ready for the next data request
        for (i = 0; i < MAX_MOTORS; i++)
        {
            if (motor_data[i].ena)
                motor_data[i].can_rx_flags = 0;  
        }
        //next data request number
        can_message_num++;
        return 1;
    }
    else
        return 0;
}

Возникает вопрос как ожидать получения всех данных? в while?
Код
while (!MOT_DataReady());

А если какой то слейв умер?
x893
Тогда сработает таймаут и большими красными буквами будет написано

ВАШЕ УСТРОЙСТВО ... СДОХЛО И НЕ ОТВЕЧАЕТ !!!
ИЩИТЕ ПАЯЛЬНИК !!!
Jenya7
Цитата(x893 @ Feb 7 2018, 12:34) *
Тогда сработает таймаут и большими красными буквами будет написано

ВАШЕ УСТРОЙСТВО ... СДОХЛО И НЕ ОТВЕЧАЕТ !!!
ИЩИТЕ ПАЯЛЬНИК !!!

а когда начать новый опрос? тут есть проблема принятия решения.
adnega
Цитата(Jenya7 @ Feb 7 2018, 10:40) *
а когда начать новый опрос? тут есть проблема принятия решения.

У вас реалтайм-система или как?
Я делаю так как писали выше. Контроллеры сами с нужной частотой шлют данные.
Мастер пакеты получает и перезапускает таймеры для каждого слейва.
В любой момент мастер имеет информацию о "свежести" данных и может либо их использовать,
либо сигнализировать о потере связи со слейвом.
Jenya7
Цитата(adnega @ Feb 7 2018, 13:30) *
У вас реалтайм-система или как?
Я делаю так как писали выше. Контроллеры сами с нужной частотой шлют данные.
Мастер пакеты получает и перезапускает таймеры для каждого слейва.
В любой момент мастер имеет информацию о "свежести" данных и может либо их использовать,
либо сигнализировать о потере связи со слейвом.

у меня слейвы не шлют данные сами по себе. они отвечают на запрос от мастера. а зачем нужны таймеры для каждого слейва?
adnega
Цитата(Jenya7 @ Feb 7 2018, 11:47) *
у меня слейвы не шлют данные сами по себе. они отвечают на запрос от мастера.

Просто нужно понимать, что слейвы могут слать данные и без запроса.
Например, мастер может сказать слейву: шли такие-то данные с такой-то периодичностью столько-то раз.

Цитата(Jenya7 @ Feb 7 2018, 11:47) *
а зачем нужны таймеры для каждого слейва?

У меня каждое устройство (узел) раз в секунду шлет SYNC-пакет с идентификационной информацией.
Мастер (я его/их называю Сервером) получает все SYNC-пакеты, пересбрасывает таймеры в таблице узлов,
при необходимости добавляет новые узлы в таблицу узлов, генерит сообщения "пропала/восстановлена" связь с узлом.
Если таймер в таблице узлов досчитал до 10 секунд, то это означает, что узел не пресылает SYNC-пакеты уже 10 секунд, а значит его нет.
Jenya7
Цитата(adnega @ Feb 7 2018, 14:15) *
Просто нужно понимать, что слейвы могут слать данные и без запроса.
Например, мастер может сказать слейву: шли такие-то данные с такой-то периодичностью столько-то раз.


У меня каждое устройство (узел) раз в секунду шлет SYNC-пакет с идентификационной информацией.
Мастер (я его/их называю Сервером) получает все SYNC-пакеты, пересбрасывает таймеры в таблице узлов,
при необходимости добавляет новые узлы в таблицу узлов, генерит сообщения "пропала/восстановлена" связь с узлом.
Если таймер в таблице узлов досчитал до 10 секунд, то это означает, что узел не пресылает SYNC-пакеты уже 10 секунд, а значит его нет.

нет. мне не нужно чтоб слейвы заваливали мастера данными когда не нужно. все четко - мастер послал запрос - получил ответ - принял решение на основе пришедших данных - послал следующий запрос.
мне только нужен красивый механизм получения ответа от слейвов. у меня слейв он реально слейв - спросили - ответил, не спросили - сидит тихо не вякает.
Сергей Борщ
QUOTE (Jenya7 @ Feb 7 2018, 11:33) *
нет. мне не нужно чтоб слейвы заваливали мастера данными когда не нужно. все четко - мастер послал запрос - получил ответ - принял решение на основе пришедших данных - послал следующий запрос.
Тогда зачем тут CAN? Потому что "стильно, модно, молодежно"? RS485 справился бы не хуже и дешевле. Изюминка CAN в том, что посылать могут все, при этом все смогут передать и конфликты будут разрешены на низком уровне в контроллере. Заложить в систему CAN и использовать его как RS485 по меньшей мере странно.
Jenya7
Цитата(Сергей Борщ @ Feb 7 2018, 14:58) *
Тогда зачем тут CAN? Потому что "стильно, модно, молодежно"? RS485 справился бы не хуже и дешевле. Изюминка CAN в том, что посылать могут все, при этом все смогут передать и конфликты будут разрешены на низком уровне в контроллере. Заложить в систему CAN и использовать его как RS485 по меньшей мере странно.

но мне реально не нужно чтоб слейвы заплевывали меня данными когда их не просят. только потому что КАН позволяет это - давайте шлите - нам не жалко? и как в таком случае отследить что я получил полный набор данных от всех слейвов?
к тому же можно поставить фильтры и слейвы получат только свои сообщения, в RS485 нужно парсить самому.

да. помню был проект. 5 узлов. все слали всем, все прекрасно работало. но там каждая посылка содержала все в себе. это был отдельный обект. а мне нужно получить все посылки от всех обыектов и чтоб посылки были синхронизированные.
AlexandrY
Цитата(Jenya7 @ Feb 7 2018, 08:20) *
Есть какое то красивое решение

Красиво будет взять STM32H7 с TT-CAN.
Baser
Так и не понял, в чем у ТС проблема?

Если хочется, чтобы было так, как сделано: CAN по опросу, то ваш мастер же знает, когда и кому он послал запрос.
Прошел установленный таймаут ответа, если есть желание, можно сделать еще одну-две попытки перезапроса,
если ответа нет - все, ошибка. Мигать красным фонарем и дудеть в пищалку.
При приходе времени очередного цикла опроса всех датчиков - попытаться опросить снова. Если все ответили - отбой тревоги, если нет, продолжаем мигать красным свистком. И далее по циклу.

Если сделать, как принято в CAN, когда датчики сами регулярно публикуют свои данные, то adnega тоже уже все подробно расписал: мастер все принимает, у него есть вся инфа, кто передал, когда.
k155la3
Цитата(adnega @ Feb 7 2018, 12:30) *
У вас реалтайм-система или как?
Я делаю так как писали выше. Контроллеры сами с нужной частотой шлют данные.
. . .

Я только начал работать с CAN.
Вопрос из тойже оперы. У меня реалтайм система (управление 3 сервоприводами, скорость CAN 250kbit ).
Изначально так и заложено, каждый серво "отстреливает" 4 раза в секунду текущую координату положения.

Так или иначе, слейвы работают асинхронно по отношению друг к другу.
То что на шине не будет коллизий указано в стандарте на CAN.
т.е. все слейвы передадут свою инф., - рано или поздно.

? 1. Для такой схемы передачи инфорамции нужно самому планировать структуру трафика по CAN ?
(при большом кол-ве слейвов )

? 2. Обязательно ли в заголовках пакетов использовать биты приоритета ?

adnega
Цитата(k155la3 @ Feb 11 2018, 02:09) *
? 1. Для такой схемы передачи инфорамции нужно самому планировать структуру трафика по CAN ?
(при большом кол-ве слейвов )

Старайтесь не грузить шину более 70%.
При высоких помехах пакеты могут теряться и их нужно будет передавать повторно (это может сделать контроллер CAN самостоятельно) -
нужно, чтобы какой-то резерв был.

Цитата(k155la3 @ Feb 11 2018, 02:09) *
? 2. Обязательно ли в заголовках пакетов использовать биты приоритета ?

С учетом обоих вопросов:
Я бы сделал разделение приоритетов для слейвов. В Идентификаторе выделил бы один из старших битов под приоритет пакета с координатами,
т.е. все более старшие биты идентификатора должны быть у всех узлов, передающих пакет с координатой одинаковым,
затем один бит приоритета (0 - высокий, 1 - низкий), остальные младшие биты могут быть адресом узла (идентификатор должен быть уникальным).
Каждый четный пакет передавать с высоким приоритетом, а каждый нечетный с низким приоритетом.
Итого: если все хорошо - все пакеты всех узлов куда надо дойдут с максимальной частотой дискретизации.
Если будут какие-то уплотнения (загрузка шины >100%), то сначала пострадает низкоприоритетный трафик,
что приведет к тому, что часть узлов будут передавать с низкой частотой дискретизации, но гарантируется,
что высокоприоритетный трафик не будет резаться, пока не срежется низкоприоритетный трафик со всех узлов.
k155la3
Цитата(adnega @ Feb 11 2018, 11:02) *
. . .

Спасибо за инф.

ZASADA
Цитата(k155la3 @ Feb 11 2018, 02:09) *
У меня реалтайм система (управление 3 сервоприводами, скорость CAN 250kbit ).
Изначально так и заложено, каждый серво "отстреливает" 4 раза в секунду текущую координату положения.

? 1. Для такой схемы передачи инфорамции нужно самому планировать структуру трафика по CAN ?
(при большом кол-ве слейвов )

при таких редких посылках можно повесить дохренилион приводов и не задумываться о загрузке шины.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.